ledger

package
v0.0.0-...-9742f5a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 29, 2020 License: Apache-2.0 Imports: 36 Imported by: 0

README

ledger

Notes

  • We support only native P2WPKH transactions (as described in BIP-0142), not P2PKH transactions, P2WPKH-in-P2SH, or other variants. P2SH transactions are not currently supported but will be in a future iteration, in order to support cross-chain atomic swaps.

P2WPKH transactions

A P2WPKH output script looks like

OP_0 [20-byte public key hash]

0x00 0x14 [20 bytes]

The constant 0 is the witness program version. It is followed by a push of the public key hash. The output address includes an address version, which identifies the address as a P2WPKH address on a particular network (testnet, goodnet, or mainnet).

An input spending a P2WPKH output must have a two witness values attached ([signature] [public key]) and an empty input script. The empty input sript is replaced with

OP_DUP OP_HASH160 [20-byte public key hash] OP_EQUALVERIFY OP_CHECKSIG

0x76 0xa9 0x14 [20 bytes] 0x88 0xac

After the output script is evaluated, the stack will look like

[20-byte public key hash]
0

The address version indicates that witnesses are in use, so the 0 is consumed (indicating the witness program version); because this is version 0, the VM checks

  • that the input script is empty;
  • that there is a single value left on the stack; and
  • that there are two witness values

and then

  • replaces the empty input script with the template above, consuming the stack; and
  • pushes the two witness values onto the stack.

After this, script execution proceeds as normal. If the public key in the witness data matches the hash embedded in the address and the signature in the witness data is valid, execution succeeds and the output may be spent.

Documentation

Index

Constants

View Source
const (
	SchemaInvalidCategory schemaParameterCategory = "invalid"
	SchemaScalar          schemaParameterCategory = "scalar"
	SchemaList            schemaParameterCategory = "list"
)
View Source
const (
	SchemaInvalidType schemaParameterType = "invalid"
	SchemaUInt64      schemaParameterType = "uint64"
	SchemaInt64       schemaParameterType = "int64"
	SchemaBytes       schemaParameterType = "[]byte"
)
View Source
const (
	TxTypeUnknown      TxType = 0x00 // Not valid in serialized transactions.
	TxTypeTransfer     TxType = 0x01
	TxTypeGenesis      TxType = 0x02
	TxTypeGlobalConfig TxType = 0x03
	TxTypeEscrowOpen   TxType = 0x10

	// XXX: this is an arbitrary limit to prevent a panic in make()
	MAX_INPUTS  = 512
	MAX_OUTPUTS = 512
	// this limit is identical with bitcoin
	MAX_FIELDLEN = 520

	MAX_CONFIGS  = 128
	MAX_KEYLEN   = 256
	MAX_VALUELEN = 512
)
View Source
const (
	AddressHashSize = 20
)
View Source
const (
	BlockIDSize = 32
)
View Source
const (
	BlockSizeLimit = 1024 * 1024 // XXX: this is an arbitrary value
)

Variables

View Source
var (
	ErrInvalidLengthBlock = fmt.Errorf("proto: negative length found during unmarshaling")
	ErrIntOverflowBlock   = fmt.Errorf("proto: integer overflow")
)
View Source
var (
	ErrBlockNotFound = fmt.Errorf("chaindb: block not found")
)

Functions

func Base58CheckDecode

func Base58CheckDecode(s string) ([]byte, error)

func MustDecodeTXID

func MustDecodeTXID(s string) models.TXID

func UvarintSize

func UvarintSize(i uint64) int

func WriteTxOut

func WriteTxOut(w io.Writer, pver uint32, version int32, to TransactionOutput) error

func WriteVarBytes

func WriteVarBytes(w io.Writer, pver uint32, bytes []byte) error

func WriteVarInt

func WriteVarInt(w io.Writer, pver uint32, val uint64) error

WriteVarInt serializes val to w using a variable number of bytes depending on its value.

Types

type Address

type Address interface {
	Bytes() []byte
	PubKeyHash() []byte
	Base58Check() string
}

func ParseAddress

func ParseAddress(s string) (Address, error)

func ParseAddressBytes

func ParseAddressBytes(data []byte) (Address, error)

type AddressVersion

type AddressVersion uint8
const (
	AddressP2WPKHMainnet AddressVersion = 0x01
	AddressP2WPKHGoodnet AddressVersion = 0x02
	AddressP2WPKHTestnet AddressVersion = 0x03
)

These values are Cachecash-specific and do not line up with Bitcoin address version assignments.

type Block

type Block struct {
	Header *BlockHeader `protobuf:"bytes,1,opt,name=Header,proto3,customtype=BlockHeader" json:"Header,omitempty"`
	// This is not a repeated field due to
	// https://github.com/gogo/protobuf/issues/478 when that is fixed this can
	// be updated to a repeated field and the plural type dropped.
	Transactions         *Transactions `protobuf:"bytes,2,opt,name=Transactions,proto3,customtype=Transactions" json:"Transactions,omitempty"`
	XXX_NoUnkeyedLiteral struct{}      `json:"-"`
	XXX_unrecognized     []byte        `json:"-"`
	XXX_sizecache        int32         `json:"-"`
}

func NewBlock

func NewBlock(sigKey ed25519.PrivateKey, previousBlock BlockID, txs []*Transaction) (*Block, error)

NewBlock creates a new block containing the given transactions and sign it

func (*Block) BlockID

func (block *Block) BlockID() BlockID

BlockID of the block header

func (*Block) CanonicalDigest

func (block *Block) CanonicalDigest() []byte

CanonicalDigest of the block header

func (*Block) Descriptor

func (*Block) Descriptor() ([]byte, []int)

func (*Block) Marshal

func (m *Block) Marshal() (dAtA []byte, err error)

func (*Block) MarshalTo

func (m *Block) MarshalTo(dAtA []byte) (int, error)

func (*Block) MerkleRoot

func (block *Block) MerkleRoot() ([]byte, error)

MerkleRoot returns a hash of all transactions

func (*Block) ProtoMessage

func (*Block) ProtoMessage()

func (*Block) Reset

func (m *Block) Reset()

func (*Block) Size

func (m *Block) Size() (n int)

func (*Block) String

func (m *Block) String() string

func (*Block) Unmarshal

func (m *Block) Unmarshal(dAtA []byte) error

func (*Block) XXX_DiscardUnknown

func (m *Block) XXX_DiscardUnknown()

func (*Block) XXX_Marshal

func (m *Block) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*Block) XXX_Merge

func (m *Block) XXX_Merge(src proto.Message)

func (*Block) XXX_Size

func (m *Block) XXX_Size() int

func (*Block) XXX_Unmarshal

func (m *Block) XXX_Unmarshal(b []byte) error

type BlockHeader

type BlockHeader struct {
	Version       uint32
	PreviousBlock BlockID // CanonicalDigest of previous block (32 bytes)
	MerkleRoot    []byte  // 32 bytes
	Timestamp     uint32
	// Bits          uint32
	// Nonce         uint32
	Random uint64 // Random bytes everyone can agree on.

	// Signature is a signature over the canonical digest of the block header.  It is produced by the centralized ledger
	// authority.
	Signature []byte
}

BlockHeader of a block containing metadata and a signature

func (BlockHeader) Marshal

func (header BlockHeader) Marshal() ([]byte, error)

func (*BlockHeader) MarshalTo

func (header *BlockHeader) MarshalTo(data []byte) (int, error)

func (*BlockHeader) Size

func (header *BlockHeader) Size() int

func (*BlockHeader) Unmarshal

func (header *BlockHeader) Unmarshal(data []byte) error

func (*BlockHeader) UnmarshalFrom

func (header *BlockHeader) UnmarshalFrom(data []byte) (int, error)

type BlockID

type BlockID [BlockIDSize]byte

func BytesToBlockID

func BytesToBlockID(x []byte) (BlockID, error)

func MustDecodeBlockID

func MustDecodeBlockID(s string) BlockID

MustDecodeBlocKID provides convenient glue for making block ID instances in code.

func (BlockID) Equal

func (bid BlockID) Equal(o BlockID) bool

func (BlockID) String

func (id BlockID) String() string

func (*BlockID) Zero

func (bid *BlockID) Zero() bool

type BlockPostgresql

type BlockPostgresql struct {
	*models.RawBlock
}

func (*BlockPostgresql) BlockID

func (block *BlockPostgresql) BlockID() []byte

func (*BlockPostgresql) Bytes

func (block *BlockPostgresql) Bytes() []byte

func (*BlockPostgresql) Height

func (block *BlockPostgresql) Height() uint64

type BlockSQL

type BlockSQL interface {
	// BlockID gets the ID of the block
	BlockID() []byte
	// Height gets the height of the block
	Height() uint64
	// Bytes gets the serialised bytes of the block
	Bytes() []byte
}

type BlockSqlite

type BlockSqlite struct {
	*models.RawBlock
}

func (*BlockSqlite) BlockID

func (block *BlockSqlite) BlockID() []byte

func (*BlockSqlite) Bytes

func (block *BlockSqlite) Bytes() []byte

func (*BlockSqlite) Height

func (block *BlockSqlite) Height() uint64

type ChainSQL

type ChainSQL interface {
	// DialectName returns the name of the SQL dialect
	DialectName() string
	// MigrationSource returns a migrate.PackrMigrationSource reference with the migrations to apply
	MigrationSource() *migrate.PackrMigrationSource
	// OneBlock retrieves a single block from the underlying store
	OneBlock(ctx context.Context, executor boil.ContextExecutor, query qm.QueryMod) (BlockSQL, error)
	// InsertBlock inserts a block into the underlying store
	InsertBlock(ctx context.Context, executor boil.ContextExecutor, blkid []byte, height uint64, bytes []byte) error
	// OneTX retrieves a single tx from the underlying store
	OneTX(ctx context.Context, executor boil.ContextExecutor, query qm.QueryMod) (TXSQL, error)
	// InsertTx inserts a block into the underlying store
	InsertTx(ctx context.Context, executor boil.ContextExecutor, txid models.TXID, bytes []byte) error
}

type ChainStorageMemory

type ChainStorageMemory struct {
	// contains filtered or unexported fields
}

ChainStorageMemory implmenets an in-memory block storage backend

func NewChainStorageMemory

func NewChainStorageMemory(genesisBlock *Block) *ChainStorageMemory

func (*ChainStorageMemory) AddBlock

func (cdb *ChainStorageMemory) AddBlock(ctx context.Context, height uint64, blk *Block) error

func (*ChainStorageMemory) AddTx

func (cdb *ChainStorageMemory) AddTx(ctx context.Context, txid models.TXID, tx *Transaction) error

func (*ChainStorageMemory) GetBlock

func (cdb *ChainStorageMemory) GetBlock(ctx context.Context, blkid BlockID) (*Block, uint64, error)

func (*ChainStorageMemory) GetTx

func (cdb *ChainStorageMemory) GetTx(ctx context.Context, txid models.TXID) (*Transaction, error)

func (*ChainStorageMemory) Height

func (cdb *ChainStorageMemory) Height(ctx context.Context) (uint64, error)

type ChainStoragePostgres

type ChainStoragePostgres struct{}

ChainStoragePostgres implements a block storage backend for postgres

func NewChainStoragePostgres

func NewChainStoragePostgres() *ChainStoragePostgres

func (*ChainStoragePostgres) DialectName

func (cdb *ChainStoragePostgres) DialectName() string

func (*ChainStoragePostgres) InsertBlock

func (cbd *ChainStoragePostgres) InsertBlock(ctx context.Context, executor boil.ContextExecutor, blkid []byte, height uint64, bytes []byte) error

func (*ChainStoragePostgres) InsertTx

func (cdb *ChainStoragePostgres) InsertTx(ctx context.Context, executor boil.ContextExecutor, txid ledger_models.TXID, bytes []byte) error

InsertTx inserts a block into the underlying store

func (*ChainStoragePostgres) MigrationSource

func (cdb *ChainStoragePostgres) MigrationSource() *migrate.PackrMigrationSource

func (*ChainStoragePostgres) OneBlock

func (cdb *ChainStoragePostgres) OneBlock(ctx context.Context, executor boil.ContextExecutor, query qm.QueryMod) (BlockSQL, error)

func (*ChainStoragePostgres) OneTX

func (cdb *ChainStoragePostgres) OneTX(ctx context.Context, executor boil.ContextExecutor, query qm.QueryMod) (TXSQL, error)

OneTX retrieves a single tx from the underlying store

type ChainStorageSQL

type ChainStorageSQL struct {
	ChainSQL
	// contains filtered or unexported fields
}

ChainStorageSQL implements a block storage backend for SQL

func NewChainStorageSQL

func NewChainStorageSQL(l *logrus.Logger, impl ChainSQL) *ChainStorageSQL

func (*ChainStorageSQL) AddBlock

func (store *ChainStorageSQL) AddBlock(ctx context.Context, height uint64, blk *Block) error

func (*ChainStorageSQL) AddTx

func (store *ChainStorageSQL) AddTx(ctx context.Context, txid models.TXID, tx *Transaction) error

func (*ChainStorageSQL) GetBlock

func (store *ChainStorageSQL) GetBlock(ctx context.Context, blkid BlockID) (*Block, uint64, error)

func (*ChainStorageSQL) GetTx

func (store *ChainStorageSQL) GetTx(ctx context.Context, txid models.TXID) (*Transaction, error)

func (*ChainStorageSQL) Height

func (store *ChainStorageSQL) Height(ctx context.Context) (uint64, error)

func (*ChainStorageSQL) RunMigrations

func (store *ChainStorageSQL) RunMigrations(db *sql.DB) error

type ChainStorageSqlite

type ChainStorageSqlite struct{}

ChainStorageSqlite implements a block storage backend for sqlite

func NewChainStorageSqlite

func NewChainStorageSqlite() *ChainStorageSqlite

func (*ChainStorageSqlite) DialectName

func (cdb *ChainStorageSqlite) DialectName() string

func (*ChainStorageSqlite) InsertBlock

func (cbd *ChainStorageSqlite) InsertBlock(ctx context.Context, executor boil.ContextExecutor, blkid []byte, height uint64, bytes []byte) error

func (*ChainStorageSqlite) InsertTx

func (cdb *ChainStorageSqlite) InsertTx(ctx context.Context, executor boil.ContextExecutor, txid ledger_models.TXID, bytes []byte) error

InsertTx inserts a block into the underlying store

func (*ChainStorageSqlite) MigrationSource

func (cdb *ChainStorageSqlite) MigrationSource() *migrate.PackrMigrationSource

func (*ChainStorageSqlite) OneBlock

func (cdb *ChainStorageSqlite) OneBlock(ctx context.Context, executor boil.ContextExecutor, query qm.QueryMod) (BlockSQL, error)

func (*ChainStorageSqlite) OneTX

func (cdb *ChainStorageSqlite) OneTX(ctx context.Context, executor boil.ContextExecutor, query qm.QueryMod) (TXSQL, error)

OneTX retrieves a single tx from the underlying store

type Database

type Database struct {
	// contains filtered or unexported fields
}

Database describes an interface to query blockchain data.

When considering transaction visiblity, remember that an individual transaction may be included in more than one block, and that the block-graph is a tree (since each block has a single parent and cycles are not possible).

TODO: Add functions for walking the block-graph.

func NewDatabase

func NewDatabase(storage Persistence) *Database

func (*Database) AddBlock

func (chain *Database) AddBlock(ctx context.Context, blk *Block) (height uint64, err error)

AddBlock adds a new block to the database. Its parent must already be in the database; no block with a matching ID may already be in the database.

Every subscriber is called and has the opportunity to error if this block would be invalid/inconsistent with their logic. Note that a new block may have an equal or lower height than the current highest block when a fork is being incorporated (to be a fork there must at least two blocks of the same height).

It is not yet clear whether all data derived from the chain should be calculated transactionally in subscriber callbacks, or nontransactionally in some sort of cache layer built above this; but for clarity, this transactional callback feature exists to provide loose coupling within the core components, not to tie together caching or other layers.

As a special case, if there are no subscribers, no transaction is created. This exists to support the in-memory DB which doesn't support transactional semantics, and for which we thus cannot support the callback mechanism.

func (*Database) GetBlock

func (chain *Database) GetBlock(ctx context.Context, blockID BlockID) (*Block, error)

func (*Database) GetTransaction

func (chain *Database) GetTransaction(ctx context.Context, cc *Position, txid models.TXID) (*Transaction, error)

GetTransaction returns a transaction by ID. If cc is non-nil, the transaction is returned only if it is visible from that position (that is, if it occurs earlier in the same block or anywhere in an ancestor block). If cc is nil, the transaction is returned no matter where it is in the block-graph.

If the transaction does not exist or is not visible from cc, returns (nil, nil).

func (*Database) Height

func (chain *Database) Height(ctx context.Context) (uint64, error)

func (*Database) Subscribe

func (chain *Database) Subscribe(subscriber NewBlockSubscriber)

Subscribe adds a new NewBlockSubscriber. The subscriber will be called back on new blocks added to the chain, within the transaction that is adding the block.

func (*Database) TransactionValid

func (cdb *Database) TransactionValid(ctx context.Context, cc *Position, tx *Transaction) error

TransactionValid determines whether a given transaction is valid at a particular place in the block-graph.

A transfer transaction is valid iff

  • it is well-formed (has no obvious syntactic/validity issues);
  • its input and output scripts are standard;
  • it spends only previously-unspent inputs;
  • all of its input scripts execute successfully when paired with the corresponding output scripts (which is where input signatures are checked); and
  • the sum of input values is *exactly* equal to the sum of output values (since we do not currently support fees).

Of these requirements, the first two can be checked in isolation.

TODO: We probably want to be able to distinguish between errors that mean "this is not a valid transaction but the mechanism worked correctly" and "something went wrong in the chain database (or somewhere else)".

XXX: We clearly need to do some refactoring. We wind up searching the chain database multiple times, parsing each script more than once, etc.

func (*Database) Unspent

func (chain *Database) Unspent(ctx context.Context, cc *Position, op Outpoint) (bool, error)

Unspent returns true iff no transaction spending the output identified by op is visible from the position in the block-graph described by cc.

type EscrowOpenTransaction

type EscrowOpenTransaction struct {
}

An EscrowOpenTransaction ...

This is a placeholder that allows us to test the code we've written to support multiple transaction types. It will be replaced with a real implementation later.

func (*EscrowOpenTransaction) Inpoints

func (tx *EscrowOpenTransaction) Inpoints() []Outpoint

func (*EscrowOpenTransaction) MarshalTo

func (tx *EscrowOpenTransaction) MarshalTo(data []byte) (n int, err error)

func (*EscrowOpenTransaction) OutputCount

func (tx *EscrowOpenTransaction) OutputCount() uint8

func (*EscrowOpenTransaction) Size

func (tx *EscrowOpenTransaction) Size() int

func (*EscrowOpenTransaction) TxInputs

func (tx *EscrowOpenTransaction) TxInputs() []TransactionInput

func (*EscrowOpenTransaction) TxOutputs

func (tx *EscrowOpenTransaction) TxOutputs() []TransactionOutput

func (*EscrowOpenTransaction) TxType

func (tx *EscrowOpenTransaction) TxType() TxType

func (*EscrowOpenTransaction) TxWitnesses

func (tx *EscrowOpenTransaction) TxWitnesses() []TransactionWitness

func (*EscrowOpenTransaction) Unmarshal

func (tx *EscrowOpenTransaction) Unmarshal(data []byte) error

func (*EscrowOpenTransaction) UnmarshalFrom

func (tx *EscrowOpenTransaction) UnmarshalFrom(data []byte) (n int, err error)

type GenesisTransaction

type GenesisTransaction struct {
	Outputs []TransactionOutput
}

A GenesisTransaction creates coins from thin air. They are only valid in the genesis block (block 0). Because we do not have coinbase transactions, we need an explicit way to get coins into the system.

func (*GenesisTransaction) Inpoints

func (tx *GenesisTransaction) Inpoints() []Outpoint

func (*GenesisTransaction) MarshalTo

func (tx *GenesisTransaction) MarshalTo(data []byte) (int, error)

func (*GenesisTransaction) OutputCount

func (tx *GenesisTransaction) OutputCount() uint8

func (*GenesisTransaction) Size

func (tx *GenesisTransaction) Size() int

func (*GenesisTransaction) TxInputs

func (tx *GenesisTransaction) TxInputs() []TransactionInput

func (*GenesisTransaction) TxOutputs

func (tx *GenesisTransaction) TxOutputs() []TransactionOutput

func (*GenesisTransaction) TxType

func (tx *GenesisTransaction) TxType() TxType

func (*GenesisTransaction) TxWitnesses

func (tx *GenesisTransaction) TxWitnesses() []TransactionWitness

func (*GenesisTransaction) Unmarshal

func (tx *GenesisTransaction) Unmarshal(data []byte) error

func (*GenesisTransaction) UnmarshalFrom

func (tx *GenesisTransaction) UnmarshalFrom(data []byte) (int, error)

type GlobalConfigListInsertion

type GlobalConfigListInsertion struct {
	Index uint64
	Value []byte
}

A GlobalConfigListInsertion describes an insertion into a list global configuration parameter (GCP).

type GlobalConfigListUpdate

type GlobalConfigListUpdate struct {
	Key string
	// Deletions is a list of indices.  Its elements must be in increasing order; duplicates are not allowed.  The
	// indices given refer to elements in the original list, before any of the deletions are processed.  For example, [0
	// 1] would delete the first two elements, not the first and third.
	Deletions []uint64
	// Insertions is a list of (Index, Value) pairs.  The given Value is inserted before the list element with the given
	// Index.  For example, an Index of 0 causes Value to be prepended to the list.  An Index equal to the length of the
	// list causes Value to be appended.  Larger values of Index are not valid.  Duplicate Values are valid.
	Insertions []GlobalConfigListInsertion
}

A GlobalConfigListUpdate describes changes to the list global configuration parameter (GCP) Key. Deletions are processed first, followed by insertions. If a Key has not been previously set, it is treated as the empty list. Individual list elements are opaque byte arrays.

func (*GlobalConfigListUpdate) MarshalTo

func (u *GlobalConfigListUpdate) MarshalTo(data []byte) (int, error)

func (*GlobalConfigListUpdate) Size

func (u *GlobalConfigListUpdate) Size() int

func (*GlobalConfigListUpdate) UnmarshalFrom

func (u *GlobalConfigListUpdate) UnmarshalFrom(data []byte) (int, error)

type GlobalConfigPatch

type GlobalConfigPatch struct {
	// How many blocks to delay activation of this patch for : convenience for operators to set something in motion
	// relatively quickly. It is an error to have both Delay and ActivationHeight non-zero.
	Delay uint64 `yaml:"delay"`
	// Alternatively, set a specific height to activate at - used when the change is far enough out that an exact height
	// can be calculated and published without racing with the authoring / publishing of the patch.
	ActivationHeight uint64                           `yaml:"activationHeight"`
	Parameters       []globalConfigPatchParameterYAML `yaml:"parameters"`
}

GlobalConfigPatch is the human supplied patch converted into GlobalConfigTransactions by cachecash-gcp merge.

func NewGlobalConfigPatch

func NewGlobalConfigPatch(content []byte) (*GlobalConfigPatch, error)

GlobalConfigSchemaYAML returns the NewGlobalConfigPatch for content provided. It will also return an error during parsing, if any.

func NewGlobalConfigPatchFromFile

func NewGlobalConfigPatchFromFile(filename string) (*GlobalConfigPatch, error)

NewGlobalConfigSchemaFromFile parses a GlobalConfigPatch file. An error is returned on IO errors, or errors propogated from NewGlobalConfigPatch

func (*GlobalConfigPatch) ToTransaction

func (p *GlobalConfigPatch) ToTransaction(ctx context.Context, chain *Database) (*GlobalConfigTransaction, error)

type GlobalConfigScalarUpdate

type GlobalConfigScalarUpdate struct {
	Key   string
	Value []byte
}

A GlobalConfigScalarUpdate indicates that the scalar gloal configuration parameter (GCP) Key has been set to Value. An empty (zero-byte) value is semantically identical to a Key that does not exist, so an update to an empty Value is equivalent to a deletion. Values are opaque byte arrays.

func (*GlobalConfigScalarUpdate) MarshalTo

func (u *GlobalConfigScalarUpdate) MarshalTo(data []byte) (int, error)

func (*GlobalConfigScalarUpdate) Size

func (u *GlobalConfigScalarUpdate) Size() int

func (*GlobalConfigScalarUpdate) UnmarshalFrom

func (u *GlobalConfigScalarUpdate) UnmarshalFrom(data []byte) (int, error)

type GlobalConfigSchema

type GlobalConfigSchema struct {
	// Parameters
	Parameters map[string]schemaParameter
}

A GlobalConfigSchema defines the available global configuration parameters in an in-memory convenient fashion.

func NewGlobalConfigSchemaFromFile

func NewGlobalConfigSchemaFromFile(filename string) (*GlobalConfigSchema, error)

NewGlobalConfigSchemaFromFile parses a GlobalConfigSchemaYAML file into a GlobalConfigSchema. An error is returned on IO errors, or errors propogated from NewGlobalConfigSchemaFromBytes

func (*GlobalConfigSchema) Generate

func (s *GlobalConfigSchema) Generate() ([]byte, error)

type GlobalConfigState

type GlobalConfigState struct {
	Scalars map[string][]byte
	Lists   map[string][][]byte
}

func NewGlobalConfigState

func NewGlobalConfigState() *GlobalConfigState

func (*GlobalConfigState) Apply

Apply returns a duplicate of st that has had the changes described in tx applied.

func (*GlobalConfigState) GetGlobalConfigSigningKeys

func (s *GlobalConfigState) GetGlobalConfigSigningKeys() ([][]byte, error)

func (*GlobalConfigState) GetUint64

func (st *GlobalConfigState) GetUint64(key string) (uint64, error)

func (*GlobalConfigState) ToYAML

ToYAML produces a GlobalConfigStateYAML, which contains known [u]int64 parameters as ints for display.

type GlobalConfigStateYAML

type GlobalConfigStateYAML struct {
	Scalars map[string]interface{}   `yaml:"scalars"`
	Lists   map[string][]interface{} `yaml:"lists"`
}

GlobalConfigStateYAML is derived from GlobalConfigState by converting the typed configuration keys into their known types. Unknown keys and byte strings are base64 encoded for output.

func NewGlobalConfigStateYAML

func NewGlobalConfigStateYAML() *GlobalConfigStateYAML

NewGlobalConfigStateYAML creates new YAML-friendly version of the GlobalConfigState. It does not come pre-populated with data from any GlobalConfigState.

type GlobalConfigTransaction

type GlobalConfigTransaction struct {
	// The changes described in this transaction become effective starting _after_ a block with the indicated height is
	// mined.
	//
	// TODO: We should set both minimum and maximum deltas between this and the height of the block in which this
	// transaction appears.  There will be a special case for the GlobalConfigTransaction that appears in the genesis
	// block.
	ActivationBlockHeight uint64

	ScalarUpdates []GlobalConfigScalarUpdate

	ListUpdates []GlobalConfigListUpdate

	// SigPublicKey is a 32-byte Ed25519 public key.  Must be one of the keys listed in the GCP `GlobalConfigKeys`.
	SigPublicKey []byte

	// Signature is a 64-byte Ed25519 signature over the transaction produced by the private key corresponding to
	// SigPublicKey.
	Signature []byte
}

A GlobalConfigTransaction creates coins from thin air. They are only valid in the genesis block (block 0). Because we do not have coinbase transactions, we need an explicit way to get coins into the system.

func (*GlobalConfigTransaction) Inpoints

func (tx *GlobalConfigTransaction) Inpoints() []Outpoint

func (*GlobalConfigTransaction) MarshalTo

func (tx *GlobalConfigTransaction) MarshalTo(data []byte) (int, error)

func (*GlobalConfigTransaction) OutputCount

func (tx *GlobalConfigTransaction) OutputCount() uint8

func (*GlobalConfigTransaction) Size

func (tx *GlobalConfigTransaction) Size() int

func (*GlobalConfigTransaction) TxInputs

func (tx *GlobalConfigTransaction) TxInputs() []TransactionInput

func (*GlobalConfigTransaction) TxOutputs

func (tx *GlobalConfigTransaction) TxOutputs() []TransactionOutput

func (*GlobalConfigTransaction) TxType

func (tx *GlobalConfigTransaction) TxType() TxType

func (*GlobalConfigTransaction) TxWitnesses

func (tx *GlobalConfigTransaction) TxWitnesses() []TransactionWitness

func (*GlobalConfigTransaction) Unmarshal

func (tx *GlobalConfigTransaction) Unmarshal(data []byte) error

func (*GlobalConfigTransaction) UnmarshalFrom

func (tx *GlobalConfigTransaction) UnmarshalFrom(data []byte) (int, error)

type HeaderStub

type HeaderStub struct {
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (*HeaderStub) Descriptor

func (*HeaderStub) Descriptor() ([]byte, []int)

func (*HeaderStub) Marshal

func (m *HeaderStub) Marshal() (dAtA []byte, err error)

func (*HeaderStub) MarshalTo

func (m *HeaderStub) MarshalTo(dAtA []byte) (int, error)

func (*HeaderStub) ProtoMessage

func (*HeaderStub) ProtoMessage()

func (*HeaderStub) Reset

func (m *HeaderStub) Reset()

func (*HeaderStub) Size

func (m *HeaderStub) Size() (n int)

func (*HeaderStub) String

func (m *HeaderStub) String() string

func (*HeaderStub) Unmarshal

func (m *HeaderStub) Unmarshal(dAtA []byte) error

func (*HeaderStub) XXX_DiscardUnknown

func (m *HeaderStub) XXX_DiscardUnknown()

func (*HeaderStub) XXX_Marshal

func (m *HeaderStub) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*HeaderStub) XXX_Merge

func (m *HeaderStub) XXX_Merge(src proto.Message)

func (*HeaderStub) XXX_Size

func (m *HeaderStub) XXX_Size() int

func (*HeaderStub) XXX_Unmarshal

func (m *HeaderStub) XXX_Unmarshal(b []byte) error

type NewBlockSubscriber

type NewBlockSubscriber interface {
	NewBlock(ctx context.Context, height uint64, block *Block) error
}

NewBlockSubscriber describes the in-transaction callback made by Database for new blocks.

type Outpoint

type Outpoint struct {
	PreviousTx models.TXID
	Index      uint8 // (of output in PreviousTx) // TODO: type
}

XXX: This is a bad name, because we use this struct to describe both inpoints and outpoints.

func (Outpoint) Equal

func (a Outpoint) Equal(b Outpoint) bool

func (*Outpoint) Key

func (o *Outpoint) Key() OutpointKey

type OutpointKey

type OutpointKey [33]byte

func NewOutpointKey

func NewOutpointKey(txid []byte, idx byte) (*OutpointKey, error)

func (*OutpointKey) Idx

func (o *OutpointKey) Idx() byte

func (OutpointKey) String

func (o OutpointKey) String() string

func (*OutpointKey) TXID

func (o *OutpointKey) TXID() models.TXID

type P2WPKHAddress

type P2WPKHAddress struct {
	AddressVersion        AddressVersion
	WitnessProgramVersion uint8 // Must be 0, as in Bitcoin.
	PublicKeyHash         []byte
}

func MakeP2WPKHAddress

func MakeP2WPKHAddress(pubKey ed25519.PublicKey) *P2WPKHAddress

func (*P2WPKHAddress) Base58Check

func (a *P2WPKHAddress) Base58Check() string

func (*P2WPKHAddress) Bytes

func (a *P2WPKHAddress) Bytes() []byte

func (*P2WPKHAddress) PubKeyHash

func (a *P2WPKHAddress) PubKeyHash() []byte

type Persistence

type Persistence interface {
	Height(ctx context.Context) (uint64, error)
	AddBlock(ctx context.Context, height uint64, blk *Block) error
	GetBlock(ctx context.Context, blkid BlockID) (*Block, uint64, error)
	AddTx(ctx context.Context, txid models.TXID, tx *Transaction) error
	GetTx(ctx context.Context, txid models.TXID) (*Transaction, error)
}

Persistence descibes the storage backend that is used to store blocks and transactions

type Position

type Position struct {
	BlockID BlockID
	TxIndex uint32
}

Position is the location of a transaction: the Nth transaction in a specific block.

type SigHashType

type SigHashType uint32
const (
	SigHashAll SigHashType = 0x1
)

type SpendingState

type SpendingState struct {
	TXs []*Transaction
	// contains filtered or unexported fields
}

SpendingState is a temporary state when crafting a new TransferTransaction Transaction in the mempool may conflict with each other, like spending the same UTXO twice. Transactions added to the SpendingState are guaranteed to be conflict free.

func NewSpendingState

func NewSpendingState() *SpendingState

func (*SpendingState) AcceptTransaction

func (s *SpendingState) AcceptTransaction(tx *Transaction)

func (*SpendingState) AcceptedTransactions

func (s *SpendingState) AcceptedTransactions() []*Transaction

func (*SpendingState) AddTx

func (s *SpendingState) AddTx(tx *Transaction) error

func (*SpendingState) IsNewUnspent

func (s *SpendingState) IsNewUnspent(key OutpointKey) *TransactionOutput

func (*SpendingState) Size

func (s *SpendingState) Size() int

func (*SpendingState) SpentUTXOs

func (s *SpendingState) SpentUTXOs() []OutpointKey

type TXSQL

type TXSQL interface {
	// TxID gets the transaction ID
	TxID() models.TXID
	// Bytes gets the serialised bytes of the transaction
	Bytes() []byte
}

type Transaction

type Transaction struct {
	Version uint8  // Must be 1.
	Flags   uint16 // Must be zero; no flags are defined for any transaction types.
	Body    TransactionBody
}

func (*Transaction) GenerateWitnesses

func (tx *Transaction) GenerateWitnesses(kp *keypair.KeyPair, prevOutputs []TransactionOutput) error

func (*Transaction) Inpoints

func (tx *Transaction) Inpoints() []Outpoint

func (*Transaction) Inputs

func (tx *Transaction) Inputs() []TransactionInput

func (Transaction) Marshal

func (tx Transaction) Marshal() ([]byte, error)

func (*Transaction) MarshalTo

func (tx *Transaction) MarshalTo(data []byte) (int, error)

func (*Transaction) Outpoints

func (tx *Transaction) Outpoints() []Outpoint

func (*Transaction) Outputs

func (tx *Transaction) Outputs() []TransactionOutput

func (*Transaction) SigHash

func (tx *Transaction) SigHash(script *txscript.Script, txIdx int, inputAmount int64) ([]byte, error)

func (*Transaction) Size

func (tx *Transaction) Size() int

func (*Transaction) Standard

func (tx *Transaction) Standard() error

func (*Transaction) TXID

func (tx *Transaction) TXID() (models.TXID, error)

func (*Transaction) Unmarshal

func (tx *Transaction) Unmarshal(data []byte) error

func (*Transaction) UnmarshalFrom

func (tx *Transaction) UnmarshalFrom(data []byte) (int, error)

N.B.: This is not strictly required for the protobuf interface, but it's useful for test code to be able to tell how many bytes were consumed.

func (*Transaction) WellFormed

func (tx *Transaction) WellFormed() error

func (*Transaction) Witnesses

func (tx *Transaction) Witnesses() []TransactionWitness

type TransactionBody

type TransactionBody interface {
	Size() int
	TxType() TxType
	MarshalTo(data []byte) (n int, err error)
	Unmarshal(data []byte) error
	UnmarshalFrom(data []byte) (n int, err error)
	Inpoints() []Outpoint
	OutputCount() uint8
	TxInputs() []TransactionInput
	TxOutputs() []TransactionOutput
	TxWitnesses() []TransactionWitness
}

type TransactionHashes

type TransactionHashes struct {
	HashPrevOuts chainhash.Hash
	HashSequence chainhash.Hash
	HashOutputs  chainhash.Hash
}

func NewTransactionHashes

func NewTransactionHashes(tx *Transaction) (*TransactionHashes, error)

type TransactionInput

type TransactionInput struct {
	Outpoint
	ScriptSig  []byte // (first half of script) // TODO: type
	SequenceNo uint32 // Normally 0xFFFFFFFF; has no effect unless the transaction has LockTime > 0.
}

func (*TransactionInput) MarshalTo

func (ti *TransactionInput) MarshalTo(data []byte) (int, error)

func (*TransactionInput) Size

func (ti *TransactionInput) Size() int

func (*TransactionInput) UnmarshalFrom

func (ti *TransactionInput) UnmarshalFrom(data []byte) (int, error)

type TransactionOutput

type TransactionOutput struct {
	Value        uint32 // (number of tokens) // TODO: type
	ScriptPubKey []byte // (second half of script) // TODO: type
}

func (*TransactionOutput) MarshalTo

func (to *TransactionOutput) MarshalTo(data []byte) (int, error)

func (*TransactionOutput) Size

func (to *TransactionOutput) Size() int

func (*TransactionOutput) UnmarshalFrom

func (to *TransactionOutput) UnmarshalFrom(data []byte) (int, error)

type TransactionWitness

type TransactionWitness struct {
	Data [][]byte
}

In Bitcoin, this is serialized as a data stack. The number of items in the stack (2, for witness data) is given as a compactSize-encoded uint. Each of the items (the signature and then the pubkey) are given a single-byte length prefix.

In Cachecash, we use a uvarint for the number of items, and then each item has a uvarint length prefix.

func (*TransactionWitness) MarshalTo

func (tw *TransactionWitness) MarshalTo(data []byte) (int, error)

func (*TransactionWitness) Size

func (tw *TransactionWitness) Size() int

func (*TransactionWitness) UnmarshalFrom

func (tw *TransactionWitness) UnmarshalFrom(data []byte) (int, error)

type Transactions

type Transactions struct {
	Transactions []*Transaction
}

Transactions wraps a slice of *Transaction

func (Transactions) Marshal

func (transactions Transactions) Marshal() ([]byte, error)

func (*Transactions) MarshalTo

func (transactions *Transactions) MarshalTo(data []byte) (int, error)

func (*Transactions) Size

func (transactions *Transactions) Size() int

func (*Transactions) Unmarshal

func (transactions *Transactions) Unmarshal(data []byte) error

func (*Transactions) UnmarshalFrom

func (transactions *Transactions) UnmarshalFrom(data []byte) (int, error)

type TransactionsStub

type TransactionsStub struct {
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (*TransactionsStub) Descriptor

func (*TransactionsStub) Descriptor() ([]byte, []int)

func (*TransactionsStub) Marshal

func (m *TransactionsStub) Marshal() (dAtA []byte, err error)

func (*TransactionsStub) MarshalTo

func (m *TransactionsStub) MarshalTo(dAtA []byte) (int, error)

func (*TransactionsStub) ProtoMessage

func (*TransactionsStub) ProtoMessage()

func (*TransactionsStub) Reset

func (m *TransactionsStub) Reset()

func (*TransactionsStub) Size

func (m *TransactionsStub) Size() (n int)

func (*TransactionsStub) String

func (m *TransactionsStub) String() string

func (*TransactionsStub) Unmarshal

func (m *TransactionsStub) Unmarshal(dAtA []byte) error

func (*TransactionsStub) XXX_DiscardUnknown

func (m *TransactionsStub) XXX_DiscardUnknown()

func (*TransactionsStub) XXX_Marshal

func (m *TransactionsStub) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*TransactionsStub) XXX_Merge

func (m *TransactionsStub) XXX_Merge(src proto.Message)

func (*TransactionsStub) XXX_Size

func (m *TransactionsStub) XXX_Size() int

func (*TransactionsStub) XXX_Unmarshal

func (m *TransactionsStub) XXX_Unmarshal(b []byte) error

type TransferTransaction

type TransferTransaction struct {
	Inputs    []TransactionInput
	Outputs   []TransactionOutput
	Witnesses []TransactionWitness
	LockTime  uint32
}

A TransferTransaction is very similar to a Bitcoin transaction. It consumes one or more unspent outputs of previous transactions (UTXOs) and produces one or more new outputs. If the sum of the outputs is larger than the sum of the inputs, the difference is collected by the miner. (For the time being, this fee MUST be zero.)

These transactions *always* have segregated witness (segwit) data. The "flags" field is mandatory (whereas it is optional in Bitcoin).

Cachecash has different restrictions for standard transactions than Bitcoin does. Currently, only pay-to-pubkey-hash (P2PKH) outputs are permitted. Pay-to-script-hash (P2SH) outputs will be added later in development.

Also, we use the same "uvarint" encoding everywhere, instead of the "compactSize" encoding that Bitcoin uses at a protocol level.

func (*TransferTransaction) Inpoints

func (tx *TransferTransaction) Inpoints() []Outpoint

func (*TransferTransaction) MarshalTo

func (tx *TransferTransaction) MarshalTo(data []byte) (int, error)

func (*TransferTransaction) OutputCount

func (tx *TransferTransaction) OutputCount() uint8

func (*TransferTransaction) Size

func (tx *TransferTransaction) Size() int

func (*TransferTransaction) TxInputs

func (tx *TransferTransaction) TxInputs() []TransactionInput

func (*TransferTransaction) TxOutputs

func (tx *TransferTransaction) TxOutputs() []TransactionOutput

func (*TransferTransaction) TxType

func (tx *TransferTransaction) TxType() TxType

func (*TransferTransaction) TxWitnesses

func (tx *TransferTransaction) TxWitnesses() []TransactionWitness

func (*TransferTransaction) Unmarshal

func (tx *TransferTransaction) Unmarshal(data []byte) error

func (*TransferTransaction) UnmarshalFrom

func (tx *TransferTransaction) UnmarshalFrom(data []byte) (int, error)

type TxPostgresql

type TxPostgresql struct {
	*models.RawTX
}

func (*TxPostgresql) Bytes

func (tx *TxPostgresql) Bytes() []byte

func (*TxPostgresql) TxID

func (tx *TxPostgresql) TxID() ledger_models.TXID

type TxSqlite

type TxSqlite struct {
	*models.RawTX
}

func (*TxSqlite) Bytes

func (tx *TxSqlite) Bytes() []byte

func (*TxSqlite) TxID

func (tx *TxSqlite) TxID() ledger_models.TXID

type TxType

type TxType uint8

type UTXOSet

type UTXOSet struct {
	// contains filtered or unexported fields
}

func NewUTXOSet

func NewUTXOSet() *UTXOSet

func (*UTXOSet) Length

func (us *UTXOSet) Length() int

func (*UTXOSet) Update

func (us *UTXOSet) Update(tx *Transaction) error

Directories

Path Synopsis
postgres
sqlite
Package txscript implements a limited subset of the Bitcoin script language.
Package txscript implements a limited subset of the Bitcoin script language.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL