opr

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Feb 3, 2020 License: MIT Imports: 30 Imported by: 2

Documentation

Overview

Copyright (c) of parts are held by the various contributors (see the CLA) Licensed under the MIT License. See LICENSE file in the project root for full license information.

Index

Constants

View Source
const (
	// 1%
	GradeBand float64 = 0.01
)
View Source
const (
	MiningPeriod = 480 // in seconds
)

Variables

LX holds an instance of lxrhash

View Source
var OPRChainID string

OPRChainID is the calculated chain id of the records chain

View Source
var PollingDataSource *polling.DataSources

TODO: Do not make this a global.

currently the OPR does the asset polling, this is bit backwards.
We should poll the asset prices, and set the OPR. Not create the OPR
and have it find it's own prices.

Functions

func ApplyBand added in v0.2.0

func ApplyBand(diff float64, band float64) float64

ApplyBand

func Avg

func Avg(list []*OraclePriceRecord) (avg []float64)

Avg computes the average answer for the price of each token reported

The list has to be in sorted in difficulty order before calling this function

func CalculateGrade

func CalculateGrade(avg []float64, opr *OraclePriceRecord, band float64) float64

CalculateGrade takes the averages and grades the individual OPRs

func CalculateMinimumDifficulty added in v0.1.0

func CalculateMinimumDifficulty(spot int, difficulty uint64, cutoff int) uint64

CalculateMinimumDifficulty

spot		The index of the difficulty param in the list. Sorted by difficulty
difficulty	The difficulty at index 'spot'
cutoff		The targeted index difficulty estimate

func CalculateMinimumDifficultyFromOPRs added in v0.1.0

func CalculateMinimumDifficultyFromOPRs(oprs []*OraclePriceRecord, cutoff int) uint64

CalculateMinimumDifficultyFromOPRs that we should submit for a block.

Params:
	oprs 		Sorted by difficulty, must be > 0 oprs
	cutoff 		Is 1 based, not 0. So cutoff 50 is at index 49.

func ComputeDifficulty added in v0.1.0

func ComputeDifficulty(oprhash, nonce []byte) (difficulty uint64)

func EffectiveHashRate added in v0.1.0

func EffectiveHashRate(min uint64, spot int) float64

The effective hashrate of the network given the difficulty of the 50th opr sorted by difficulty. Using https://github.com/WhoSoup/pegnet/wiki/Mining-Probabilities

func ExpectedMinimumDifficulty added in v0.1.0

func ExpectedMinimumDifficulty(hashrate float64, spot int) uint64

ExpectedMinimumDifficulty will report what minimum difficulty we would expect given a hashrate for a given position. Using https://github.com/WhoSoup/pegnet/wiki/Mining-Probabilities#expected-minimum-difficulty

func GetRewardFromPlace added in v0.1.0

func GetRewardFromPlace(place int, network string, height int64) int64

func InitDataSource added in v0.1.0

func InitDataSource(config *config.Config)

func InitLX added in v0.1.0

func InitLX()

The init function for LX is expensive. So we should explicitly call the init if we intend to use it. Make the init call idempotent

func ValidFCTAddress added in v0.2.0

func ValidFCTAddress(addr string) bool

ValidFCTAddress will be removed in the grading module refactor. This is just temporary to get this functionality, and be easily unit testable.

func VerifyWinners added in v0.1.0

func VerifyWinners(opr *OraclePriceRecord, winners []*OraclePriceRecord) bool

VerifyWinners takes an opr and compares its list of winners to the winners of previousHeight

Types

type ChainRecorder added in v0.1.0

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

ChainRecorder is a tool to create csvs to look at things on chain

func NewChainRecorder added in v0.1.0

func NewChainRecorder(con *config.Config, filpath string) (*ChainRecorder, error)

func (*ChainRecorder) WriteMinerCSV added in v0.1.0

func (c *ChainRecorder) WriteMinerCSV() error

WriteMinerCSV will write all the miner related stats for a given chain to a csv. This includes number of records, difficulties hit, and more.

func (*ChainRecorder) WritePriceCSV added in v0.2.0

func (c *ChainRecorder) WritePriceCSV(db database.IDatabase, height int64) error

type EntryBlockMarker added in v0.2.0

type EntryBlockMarker struct {
	KeyMr      string
	EntryBlock *factom.EBlock
}

func NewEntryBlockMarker added in v0.2.0

func NewEntryBlockMarker() *EntryBlockMarker

func (*EntryBlockMarker) IsSameAs added in v0.2.0

func (a *EntryBlockMarker) IsSameAs(b *EntryBlockMarker) bool

type EntryBlockMarkerList added in v0.2.0

type EntryBlockMarkerList []EntryBlockMarker

func (EntryBlockMarkerList) Len added in v0.2.0

func (p EntryBlockMarkerList) Len() int

func (EntryBlockMarkerList) Less added in v0.2.0

func (p EntryBlockMarkerList) Less(i, j int) bool

func (EntryBlockMarkerList) Swap added in v0.2.0

func (p EntryBlockMarkerList) Swap(i, j int)

type EntryBlockSync added in v0.2.0

type EntryBlockSync struct {
	ChainID          string             // Chainid of the eblock chain
	Current          EntryBlockMarker   // The current eblock we have synced
	Target           EntryBlockMarker   // The target is the chainhead
	BlocksToBeParsed []EntryBlockMarker // The eblocks between the current and target (including target)
}

EntryBlockSync has the current eblock synced to, and the target Eblock

It also has the blocks in between in order. This makes it so traversing only needs to happen once

func NewEntryBlockSync added in v0.2.0

func NewEntryBlockSync(chainid string) *EntryBlockSync

func (*EntryBlockSync) AddNewHead added in v0.2.0

func (a *EntryBlockSync) AddNewHead(keymr string, eblock *factom.EBlock)

func (*EntryBlockSync) AddNewHeadMarker added in v0.2.0

func (a *EntryBlockSync) AddNewHeadMarker(marker EntryBlockMarker)

AddNewHead will add a new eblock to be parsed to the head (tail of list)

Since the block needs to be parsed, it is the new target and added to the blocks to be parsed

func (*EntryBlockSync) BlockParsed added in v0.2.0

func (a *EntryBlockSync) BlockParsed(block EntryBlockMarker)

BlockParsed indicates a block has been parsed. We update our current

func (*EntryBlockSync) Head added in v0.2.0

func (a *EntryBlockSync) Head() EntryBlockMarker

Head returns our target head. This is the chainhead that we know of

func (*EntryBlockSync) IsSameAs added in v0.2.0

func (a *EntryBlockSync) IsSameAs(b *EntryBlockSync) bool

func (*EntryBlockSync) NextEBlock added in v0.2.0

func (a *EntryBlockSync) NextEBlock() *EntryBlockMarker

NextEBlock returns the next eblock that is needed to be parsed

func (*EntryBlockSync) SyncBlocks added in v0.2.0

func (a *EntryBlockSync) SyncBlocks() error

SyncBlocks will query factomd and check if the chainhead has been updated, and fill in the non synced eblocks

func (*EntryBlockSync) Synced added in v0.2.0

func (a *EntryBlockSync) Synced() bool

Synced returns if fully synced (current == target)

type FakeGrader added in v0.1.0

type FakeGrader struct {
	*QuickGrader
}

FakeGrader can be used in unit tests

func NewFakeGrader added in v0.1.0

func NewFakeGrader(config *config.Config, balances *balances.BalanceTracker) *FakeGrader

func (*FakeGrader) EmitFakeEvent added in v0.1.0

func (f *FakeGrader) EmitFakeEvent(event OPRs)

type IGrader added in v0.1.0

type IGrader interface {
	GetAlert(id string) (alert chan *OPRs)
	StopAlert(id string)
	Run(monitor *common.Monitor, ctx context.Context)
}

type IOPRBlockStore added in v0.2.0

type IOPRBlockStore interface {
	WriteInvalidOPRBlock(dbht int64) error
	WriteOPRBlock(opr *OprBlock) error
	FetchOPRBlock(height int64) (*OprBlock, error)
	Close() error
}

type NonceRanking added in v0.1.0

type NonceRanking struct {
	// Keep determines the depth of the list.
	// If you wish to keep the top 10 OPRs, set the keep to 10.
	Keep int

	List []*UniqueOPRData

	// Ability to set a minimum difficulty threshold
	// TODO: Set the minimum difficulty based on the previous block.
	//		 That way we don't submit oprs to the network if we know they will lose.
	MinimumDifficulty uint64

	WorstDiff  uint64 // Keep track of the worst difficulty to make the lookup cheap
	WorstIndex int
	// contains filtered or unexported fields
}

NonceRanking is a sorted list of nonces and their difficulties.

It allows us to only keep the top X oprs.

func MergeNonceRankings added in v0.1.0

func MergeNonceRankings(keep int, rankings ...*NonceRanking) *NonceRanking

MergeNonceRankings will merge a set of rankings lists into 1

func NewNonceRanking added in v0.1.0

func NewNonceRanking(keep int) *NonceRanking

func (*NonceRanking) AddNonce added in v0.1.0

func (r *NonceRanking) AddNonce(nonce []byte, difficulty uint64) bool

AddNonce will only add the nonce information if it is better than the current worst or we have extra room that is not taken in the list.

func (*NonceRanking) GetNonces added in v0.1.0

func (r *NonceRanking) GetNonces() []*UniqueOPRData

GetNonces returns the sorted nonce list

type OPRBlockDatabaseObject added in v0.2.0

type OPRBlockDatabaseObject struct {
	GradedOprs         []*OraclePriceRecord
	DblockHeight       int64
	EmptyOPRBlock      bool
	TotalNumberRecords int
}

func (*OPRBlockDatabaseObject) ToOPRBlock added in v0.2.0

func (o *OPRBlockDatabaseObject) ToOPRBlock() *OprBlock

type OPRBlockStore added in v0.2.0

type OPRBlockStore struct {
	DB database.IDatabase
}

OPRBlockStore is where we store the oprblock list

func NewOPRBlockStore added in v0.2.0

func NewOPRBlockStore(db database.IDatabase) *OPRBlockStore

func (*OPRBlockStore) Close added in v0.2.0

func (d *OPRBlockStore) Close() error

func (*OPRBlockStore) FetchOPRBlock added in v0.2.0

func (d *OPRBlockStore) FetchOPRBlock(height int64) (*OprBlock, error)

func (*OPRBlockStore) WriteInvalidOPRBlock added in v0.2.0

func (d *OPRBlockStore) WriteInvalidOPRBlock(dbht int64) error

WriteInvalidOPRBlock is for writing a dbht to disk that has an invalid oprblock. This could be because the oprblock does not have enough entries, or another error

func (*OPRBlockStore) WriteOPRBlock added in v0.2.0

func (d *OPRBlockStore) WriteOPRBlock(opr *OprBlock) error

WriteOPRBlock will write the top 50 graded oprs and write their corresponding indexes

type OPRWorkRequest added in v0.2.0

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

type OPRWorkResponse added in v0.2.0

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

type OPRs

type OPRs struct {
	ToBePaid   []*OraclePriceRecord
	GradedOPRs []*OraclePriceRecord

	// Since this is used as a message, we need a way to send an error
	Error error
}

OPRs is the message sent by the Grader

type OprBlock added in v0.1.0

type OprBlock struct {
	OPRs               []*OraclePriceRecord
	GradedOPRs         []*OraclePriceRecord
	Dbht               int64
	TotalNumberRecords int  // We tend to only keep the top 50, it's nice to know how many existed before we cut it
	EmptyOPRBlock      bool // An empty opr block is an eblock that could not totally validate
}

block data at a specific height

type OraclePriceRecord

type OraclePriceRecord struct {
	// These fields are not part of the OPR, but track values associated with the OPR.
	Protocol           string  `json:"-"` // The Protocol we are running on (PegNet)
	Network            string  `json:"-"` // The network we are running on (TestNet vs MainNet)
	Difficulty         uint64  `json:"-"` // The difficulty of the given nonce
	Grade              float64 `json:"-"` // The grade when OPR records are compared
	OPRHash            []byte  `json:"-"` // The hash of the OPR record (used by PegNet Mining)
	OPRChainID         string  `json:"-"` // [base58]  Chain ID of the chain used by the Oracle Miners
	CoinbasePEGAddress string  `json:"-"` // [base58]  PEG Address to pay PEG

	// This can be attached to an OPR, which indicates how low we should expect a mined
	// opr to be. Any OPRs mined below this are not worth submitting to the network.
	MinimumDifficulty uint64 `json:"-"`

	// Factom Entry data
	EntryHash              []byte `json:"-"` // Entry to record this record
	Nonce                  []byte `json:"-"` // Nonce used with OPR
	SelfReportedDifficulty []byte `json:"-"` // Miners self report their difficulty
	Version                uint8  `json:"-"`

	// These values define the context of the OPR, and they go into the PegNet OPR record, and are mined.
	CoinbaseAddress string   `json:"coinbase"` // [base58]  PEG Address to pay PEG
	Dbht            int32    `json:"dbht"`     //           The Directory Block Height of the OPR.
	WinPreviousOPR  []string `json:"winners"`  // First 8 bytes of the Entry Hashes of the previous winners
	FactomDigitalID string   `json:"minerid"`  // [unicode] Digital Identity of the miner

	// The Oracle values of the OPR, they are the meat of the OPR record, and are mined.
	Assets OraclePriceRecordAssetList `json:"assets"`
}

OraclePriceRecord is the data used and created by miners

func GradeMinimum added in v0.2.0

func GradeMinimum(orderedList []*OraclePriceRecord, network string, dbht int64) (graded []*OraclePriceRecord)

GradeMinimum only grades the top 50 honest records. The input must be the records sorted by self reported difficulty.

func NewOpr

func NewOpr(ctx context.Context, minerNumber int, dbht int32, c *config.Config, alert chan *OPRs) (opr *OraclePriceRecord, err error)

NewOpr collects all the information unique to this miner and its configuration, and also goes and gets the oracle data. Also collects the winners from the prior block and puts their entry hashes (base58) into this OPR

func NewOraclePriceRecord added in v0.1.0

func NewOraclePriceRecord() *OraclePriceRecord

func RemoveDuplicateSubmissions added in v0.1.0

func RemoveDuplicateSubmissions(list []*OraclePriceRecord) []*OraclePriceRecord

RemoveDuplicateSubmissions filters out any duplicate OPR (same nonce and OPRHash)

func (*OraclePriceRecord) CloneEntryData added in v0.1.0

func (c *OraclePriceRecord) CloneEntryData() *OraclePriceRecord

CloneEntryData will clone the OPR data needed to make a factom entry.

This needs to be done because I need to marshal this into my factom entry.

func (*OraclePriceRecord) ComputeDifficulty

func (opr *OraclePriceRecord) ComputeDifficulty(nonce []byte) (difficulty uint64)

ComputeDifficulty gets the difficulty by taking the hash of the OPRHash appended by the nonce. The difficulty is the highest 8 bytes of the hash taken as uint64 in Big Endian

func (*OraclePriceRecord) CreateOPREntry added in v0.1.0

func (opr *OraclePriceRecord) CreateOPREntry(nonce []byte, difficulty uint64) (*factom.Entry, error)

CreateOPREntry will create the entry from the EXISITING data. It will not set any fields like in `GetOPRecord`

func (*OraclePriceRecord) GetHash

func (opr *OraclePriceRecord) GetHash() []byte

GetHash returns the LXHash over the OPR's json representation

func (*OraclePriceRecord) GetOPRecord

func (opr *OraclePriceRecord) GetOPRecord(c *config.Config) error

GetOPRecord initializes the OPR with polling data and factom entry

func (*OraclePriceRecord) GetTokens

func (opr *OraclePriceRecord) GetTokens() (tokens []Token)

GetTokens creates an iterateable slice of Tokens containing all the currency values

func (*OraclePriceRecord) LogFieldsShort added in v0.1.0

func (opr *OraclePriceRecord) LogFieldsShort() log.Fields

LogFieldsShort returns a set of common fields to be included in logrus

func (*OraclePriceRecord) SafeMarshal added in v0.2.0

func (opr *OraclePriceRecord) SafeMarshal() ([]byte, error)

SafeMarshal will marshal the json depending on the opr version

func (*OraclePriceRecord) SafeUnmarshal added in v0.2.0

func (opr *OraclePriceRecord) SafeUnmarshal(data []byte) error

SafeMarshal will unmarshal the json depending on the opr version

func (*OraclePriceRecord) SetPegValues

func (opr *OraclePriceRecord) SetPegValues(assets polling.PegAssets)

SetPegValues assigns currency polling values to the OPR

func (*OraclePriceRecord) ShortString

func (opr *OraclePriceRecord) ShortString() string

ShortString returns a human readable string with select data

func (*OraclePriceRecord) String

func (opr *OraclePriceRecord) String() (str string)

String returns a human readable string for the Oracle Record

func (*OraclePriceRecord) Validate added in v0.1.0

func (opr *OraclePriceRecord) Validate(c *config.Config, dbht int64) bool

Validate performs sanity checks of the structure and values of the OPR. It does not validate the winners of the previous block.

type OraclePriceRecordAssetList added in v0.1.0

type OraclePriceRecordAssetList map[string]uint64

OraclePriceRecordAssetList is used such that the marshaling of the assets is in the same order, and we still can use map access in the code

func (OraclePriceRecordAssetList) Contains added in v0.1.0

func (o OraclePriceRecordAssetList) Contains(list []string) bool

func (OraclePriceRecordAssetList) ContainsExactly added in v0.1.0

func (o OraclePriceRecordAssetList) ContainsExactly(list []string) bool

func (OraclePriceRecordAssetList) List added in v0.1.0

func (o OraclePriceRecordAssetList) List(version uint8) []Token

List returns the list of assets in the global order

func (OraclePriceRecordAssetList) MarshalJSON added in v0.1.0

func (o OraclePriceRecordAssetList) MarshalJSON() ([]byte, error)

from https://github.com/iancoleman/orderedmap/blob/master/orderedmap.go#L310

func (OraclePriceRecordAssetList) SetValue added in v0.2.0

func (o OraclePriceRecordAssetList) SetValue(asset string, value float64)

SetValue converts the float to uint64 Deprecated: Should not be using floats, stick to the uint64

func (OraclePriceRecordAssetList) SetValueFromUint64 added in v0.2.0

func (o OraclePriceRecordAssetList) SetValueFromUint64(asset string, value uint64)

func (OraclePriceRecordAssetList) Uint64Value added in v0.2.0

func (o OraclePriceRecordAssetList) Uint64Value(asset string) uint64

Uint64Value returns 0 for empty assets

func (OraclePriceRecordAssetList) UnmarshalJSON added in v0.2.0

func (o OraclePriceRecordAssetList) UnmarshalJSON(data []byte) error

func (OraclePriceRecordAssetList) Value added in v0.2.0

func (o OraclePriceRecordAssetList) Value(asset string) float64

Value converts the value to a float Deprecated: Should not be using floats, stick to the uint64

type QuickGrader added in v0.2.0

type QuickGrader struct {
	Network          string
	Protocol         string
	OPRChainID       []byte
	OPRChainIDString string

	Balances *balances.BalanceTracker
	Burns    *balances.BurnTracking
	OPRChain *EntryBlockSync

	Config *config.Config

	BlockStore IOPRBlockStore
	// contains filtered or unexported fields
}

QuickGrader is responsible for evaluating the previous block of OPRs and determines who should be paid. It will only check the minimum number of OPR records. This also informs the miners which records should be included in their OPR records

func NewQuickGrader added in v0.2.0

func NewQuickGrader(config *config.Config, db database.IDatabase, balanceTraker *balances.BalanceTracker) *QuickGrader

func (*QuickGrader) Close added in v0.2.0

func (g *QuickGrader) Close() error

func (*QuickGrader) DEBUGAddOPRBlock added in v0.2.0

func (g *QuickGrader) DEBUGAddOPRBlock(oprBlock *OprBlock)

DEBUGAddOPRBlock is used for unit tests. We need access to the private field to setup some basic testing

func (*QuickGrader) FetchOPRBlock added in v0.2.0

func (g *QuickGrader) FetchOPRBlock(block *EntryBlockMarker) (*OprBlock, error)

func (*QuickGrader) GetAlert added in v0.2.0

func (g *QuickGrader) GetAlert(id string) (alert chan *OPRs)

GetAlert registers a new request for alerts. Data will be sent when the grades from the last block are ready

func (*QuickGrader) GetBlocks added in v0.2.0

func (g *QuickGrader) GetBlocks() []*OprBlock

GetBlocks should only be used in unit tests. It is not thread safe

func (*QuickGrader) GetFirstOPRBlock added in v0.2.0

func (g *QuickGrader) GetFirstOPRBlock() *OprBlock

func (*QuickGrader) GetPreviousOPRBlock added in v0.2.0

func (g *QuickGrader) GetPreviousOPRBlock(dbht int32) *OprBlock

GetPreviousOPRBlock returns the winners of the previous OPR block

func (*QuickGrader) GetPreviousOPRs added in v0.2.0

func (g *QuickGrader) GetPreviousOPRs(dbht int32) []*OraclePriceRecord

GetPreviousOPRs returns the OPRs in highest-known block less than dbht. Returns nil if the dbht is the first dbht in the chain.

func (*QuickGrader) GetPreviousWinners added in v0.2.0

func (g *QuickGrader) GetPreviousWinners(dbht int32) (winners []*OraclePriceRecord)

func (*QuickGrader) MinRecords added in v0.2.0

func (g *QuickGrader) MinRecords(dbht int64) int

func (*QuickGrader) OprBlockByHeight added in v0.2.0

func (g *QuickGrader) OprBlockByHeight(dbht int64) *OprBlock

oprBlockByHeight returns a single OPRBlock

func (*QuickGrader) OprByHash added in v0.2.0

func (g *QuickGrader) OprByHash(hash string) OraclePriceRecord

oprByHash returns the entire OPR based on it's entry hash

func (*QuickGrader) OprByShortHash added in v0.2.0

func (g *QuickGrader) OprByShortHash(shorthash string) OraclePriceRecord

Failing tests. Need to grok how the short 8 byte winning oprhashes are done.

func (*QuickGrader) OprsByDigitalID added in v0.2.0

func (g *QuickGrader) OprsByDigitalID(did string) []OraclePriceRecord

oprsByDigitalID returns every OPR created by a given ID Multiple ID's per miner or single daemon are possible. This function searches through every possible ID and returns all.

func (*QuickGrader) ParallelFetchOPRsFromEBlock added in v0.2.0

func (g *QuickGrader) ParallelFetchOPRsFromEBlock(block *EntryBlockMarker, workerCount int, enforceWinners bool) ([]*OraclePriceRecord, error)

ParallelFetchOPRsFromEBlock is so we can parallelize our factomd requests.

Params:
	block
	workerCount		Number of parallel outbound requests
	enforceWinners	Verify the previous winners

func (*QuickGrader) ParseOPREntry added in v0.2.0

func (g *QuickGrader) ParseOPREntry(entry *factom.Entry, height int64) (*OraclePriceRecord, error)

ParseOPREntry will return the oracle price record for a given entry.

Returns:
	(opr, nil)		Entry is OPR and no errors
	(nil, nil)		Entry is not an OPR and no errors
	(nil, error)	We don't know, we should not check this eblock as processed

func (*QuickGrader) Run added in v0.2.0

func (g *QuickGrader) Run(monitor *common.Monitor, ctx context.Context)

func (*QuickGrader) SendToListeners added in v0.2.0

func (g *QuickGrader) SendToListeners(winners *OPRs)

func (*QuickGrader) StopAlert added in v0.2.0

func (g *QuickGrader) StopAlert(id string)

StopAlert allows cleanup of alerts that are no longer used

func (*QuickGrader) Sync added in v0.2.0

func (g *QuickGrader) Sync() error

Sync will sync our opr chain to the latest eblock head of the OPR chain

type Token

type Token struct {
	Code  string
	Value float64
}

Token is a combination of currency Code and Value

type UniqueOPRData added in v0.1.0

type UniqueOPRData struct {
	Nonce      []byte
	Difficulty uint64
}

UniqueOPRData is the minimum set of information we need to change for our OPR submissions

func SortNonceRanks added in v0.1.0

func SortNonceRanks(list []*UniqueOPRData) []*UniqueOPRData

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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