本文整理汇总了Golang中github.com/decred/dcrutil.Block.MsgBlock方法的典型用法代码示例。如果您正苦于以下问题:Golang Block.MsgBlock方法的具体用法?Golang Block.MsgBlock怎么用?Golang Block.MsgBlock使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类github.com/decred/dcrutil.Block
的用法示例。
在下文中一共展示了Block.MsgBlock方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: LogBlockHeight
// LogBlockHeight logs a new block height as an information message to show
// progress to the user. In order to prevent spam, it limits logging to one
// message every 10 seconds with duration and totals included.
func (b *blockProgressLogger) LogBlockHeight(block *dcrutil.Block) {
b.Lock()
defer b.Unlock()
b.receivedLogBlocks++
b.receivedLogTx += int64(len(block.MsgBlock().Transactions))
now := time.Now()
duration := now.Sub(b.lastBlockLogTime)
if duration < time.Second*10 {
return
}
// Truncate the duration to 10s of milliseconds.
durationMillis := int64(duration / time.Millisecond)
tDuration := 10 * time.Millisecond * time.Duration(durationMillis/10)
// Log information about new block height.
blockStr := "blocks"
if b.receivedLogBlocks == 1 {
blockStr = "block"
}
txStr := "transactions"
if b.receivedLogTx == 1 {
txStr = "transaction"
}
b.subsystemLogger.Infof("%s %d %s in the last %s (%d %s, height %d, %s)",
b.progressAction, b.receivedLogBlocks, blockStr, tDuration, b.receivedLogTx,
txStr, block.Height(), block.MsgBlock().Header.Timestamp)
b.receivedLogBlocks = 0
b.receivedLogTx = 0
b.lastBlockLogTime = now
}
示例2: checkBlockContext
// checkBlockContext peforms several validation checks on the block which depend
// on its position within the block chain.
//
// The flags modify the behavior of this function as follows:
// - BFFastAdd: The transaction are not checked to see if they are finalized
// and the somewhat expensive duplication transaction check is not performed.
//
// The flags are also passed to checkBlockHeaderContext. See its documentation
// for how the flags modify its behavior.
func (b *BlockChain) checkBlockContext(block *dcrutil.Block, prevNode *blockNode,
flags BehaviorFlags) error {
// The genesis block is valid by definition.
if prevNode == nil {
return nil
}
// Perform all block header related validation checks.
header := &block.MsgBlock().Header
err := b.checkBlockHeaderContext(header, prevNode, flags)
if err != nil {
return err
}
fastAdd := flags&BFFastAdd == BFFastAdd
if !fastAdd {
// The height of this block is one more than the referenced
// previous block.
blockHeight := prevNode.height + 1
// Ensure all transactions in the block are finalized.
for _, tx := range block.Transactions() {
if !IsFinalizedTransaction(tx, blockHeight,
header.Timestamp) {
str := fmt.Sprintf("block contains unfinalized regular "+
"transaction %v", tx.Sha())
return ruleError(ErrUnfinalizedTx, str)
}
}
for _, stx := range block.STransactions() {
if !IsFinalizedTransaction(stx, blockHeight,
header.Timestamp) {
str := fmt.Sprintf("block contains unfinalized stake "+
"transaction %v", stx.Sha())
return ruleError(ErrUnfinalizedTx, str)
}
}
// Check that the node is at the correct height in the blockchain,
// as specified in the block header.
if blockHeight != int64(block.MsgBlock().Header.Height) {
errStr := fmt.Sprintf("Block header height invalid; expected %v"+
" but %v was found", blockHeight, header.Height)
return ruleError(ErrBadBlockHeight, errStr)
}
// Check that the coinbase contains at minimum the block
// height in output 1.
if blockHeight > 1 {
err := checkCoinbaseUniqueHeight(blockHeight, block)
if err != nil {
return err
}
}
}
return nil
}
示例3: dbIndexDisconnectBlock
// dbIndexDisconnectBlock removes all of the index entries associated with the
// given block using the provided indexer and updates the tip of the indexer
// accordingly. An error will be returned if the current tip for the indexer is
// not the passed block.
func dbIndexDisconnectBlock(dbTx database.Tx, indexer Indexer, block, parent *dcrutil.Block, view *blockchain.UtxoViewpoint) error {
// Assert that the block being disconnected is the current tip of the
// index.
idxKey := indexer.Key()
curTipHash, _, err := dbFetchIndexerTip(dbTx, idxKey)
if err != nil {
return err
}
if !curTipHash.IsEqual(block.Sha()) {
return AssertError(fmt.Sprintf("dbIndexDisconnectBlock must "+
"be called with the block at the current index tip "+
"(%s, tip %s, block %s)", indexer.Name(),
curTipHash, block.Sha()))
}
// Notify the indexer with the disconnected block so it can remove all
// of the appropriate entries.
if err := indexer.DisconnectBlock(dbTx, block, parent, view); err != nil {
return err
}
// Update the current index tip.
prevHash := &block.MsgBlock().Header.PrevBlock
return dbPutIndexerTip(dbTx, idxKey, prevHash, uint32(block.Height())-1)
}
示例4: submitBlock
// submitBlock submits the passed block to network after ensuring it passes all
// of the consensus validation rules.
func (m *CPUMiner) submitBlock(block *dcrutil.Block) bool {
m.submitBlockLock.Lock()
defer m.submitBlockLock.Unlock()
_, latestHeight := m.server.blockManager.chainState.Best()
// Be sure to set this so ProcessBlock doesn't fail! - Decred
block.SetHeight(latestHeight + 1)
// Process this block using the same rules as blocks coming from other
// nodes. This will in turn relay it to the network like normal.
isOrphan, err := m.server.blockManager.ProcessBlock(block, blockchain.BFNone)
if err != nil {
// Anything other than a rule violation is an unexpected error,
// so log that error as an internal error.
if rErr, ok := err.(blockchain.RuleError); !ok {
minrLog.Errorf("Unexpected error while processing "+
"block submitted via CPU miner: %v", err)
return false
} else {
// Occasionally errors are given out for timing errors with
// ResetMinDifficulty and high block works that is above
// the target. Feed these to debug.
if m.server.chainParams.ResetMinDifficulty &&
rErr.ErrorCode == blockchain.ErrHighHash {
minrLog.Debugf("Block submitted via CPU miner rejected "+
"because of ResetMinDifficulty time sync failure: %v",
err)
return false
} else {
// Other rule errors should be reported.
minrLog.Errorf("Block submitted via CPU miner rejected: %v", err)
return false
}
}
}
if isOrphan {
minrLog.Errorf("Block submitted via CPU miner is an orphan building "+
"on parent %v", block.MsgBlock().Header.PrevBlock)
return false
}
// The block was accepted.
coinbaseTxOuts := block.MsgBlock().Transactions[0].TxOut
coinbaseTxGenerated := int64(0)
for _, out := range coinbaseTxOuts {
coinbaseTxGenerated += out.Value
}
minrLog.Infof("Block submitted via CPU miner accepted (hash %s, "+
"height %v, amount %v)",
block.Sha(),
block.Height(),
dcrutil.Amount(coinbaseTxGenerated))
return true
}
示例5: ticketsRevokedInBlock
// ticketsRevokedInBlock fetches a list of tickets that were revoked in the
// block.
func ticketsRevokedInBlock(bl *dcrutil.Block) []chainhash.Hash {
var tickets []chainhash.Hash
for _, stx := range bl.MsgBlock().STransactions {
if stake.DetermineTxType(stx) == stake.TxTypeSSRtx {
tickets = append(tickets, stx.TxIn[0].PreviousOutPoint.Hash)
}
}
return tickets
}
示例6: voteVersionsInBlock
// voteVersionsInBlock returns all versions in a block.
func voteVersionsInBlock(bl *dcrutil.Block, params *chaincfg.Params) []uint32 {
versions := make([]uint32, 0, params.TicketsPerBlock)
for _, stx := range bl.MsgBlock().STransactions {
if is, _ := stake.IsSSGen(stx); !is {
continue
}
versions = append(versions, stake.SSGenVersion(stx))
}
return versions
}
示例7: lookupTransaction
// lookupTransaction is a special transaction lookup function that searches
// the database, the block, and its parent for a transaction. This is needed
// because indexBlockAddrs is called AFTER a block is added/removed in the
// blockchain in blockManager, necessitating that the blocks internally be
// searched for inputs for any given transaction too. Additionally, it's faster
// to get the tx from the blocks here since they're already
func (a *addrIndexer) lookupTransaction(txHash chainhash.Hash, blk *dcrutil.Block,
parent *dcrutil.Block) (*wire.MsgTx, error) {
// Search the previous block and parent first.
txTreeRegularValid := dcrutil.IsFlagSet16(blk.MsgBlock().Header.VoteBits,
dcrutil.BlockValid)
// Search the regular tx tree of this and the last block if the
// tx tree regular was validated.
if txTreeRegularValid {
for _, stx := range parent.STransactions() {
if stx.Sha().IsEqual(&txHash) {
return stx.MsgTx(), nil
}
}
for _, tx := range parent.Transactions() {
if tx.Sha().IsEqual(&txHash) {
return tx.MsgTx(), nil
}
}
for _, tx := range blk.Transactions() {
if tx.Sha().IsEqual(&txHash) {
return tx.MsgTx(), nil
}
}
} else {
// Just search this block's regular tx tree and the previous
// block's stake tx tree.
for _, stx := range parent.STransactions() {
if stx.Sha().IsEqual(&txHash) {
return stx.MsgTx(), nil
}
}
for _, tx := range blk.Transactions() {
if tx.Sha().IsEqual(&txHash) {
return tx.MsgTx(), nil
}
}
}
// Lookup and fetch the referenced output's tx in the database.
txList, err := a.server.db.FetchTxBySha(&txHash)
if err != nil {
adxrLog.Errorf("Error fetching tx %v: %v",
txHash, err)
return nil, err
}
if len(txList) == 0 {
return nil, fmt.Errorf("transaction %v not found",
txHash)
}
return txList[len(txList)-1].Tx, nil
}
示例8: checkCoinbaseUniqueHeight
// checkCoinbaseUniqueHeight checks to ensure that for all blocks height > 1
// that the coinbase contains the height encoding to make coinbase hash collisions
// impossible.
func checkCoinbaseUniqueHeight(blockHeight int64, block *dcrutil.Block) error {
if !(len(block.MsgBlock().Transactions) > 0) {
str := fmt.Sprintf("block %v has no coinbase", block.Sha())
return ruleError(ErrNoTransactions, str)
}
// Coinbase TxOut[0] is always tax, TxOut[1] is always
// height + extranonce, so at least two outputs must
// exist.
if !(len(block.MsgBlock().Transactions[0].TxOut) > 1) {
str := fmt.Sprintf("block %v is missing necessary coinbase "+
"outputs", block.Sha())
return ruleError(ErrFirstTxNotCoinbase, str)
}
// The first 4 bytes of the NullData output must be the
// encoded height of the block, so that every coinbase
// created has a unique transaction hash.
nullData, err := txscript.GetNullDataContent(
block.MsgBlock().Transactions[0].TxOut[1].Version,
block.MsgBlock().Transactions[0].TxOut[1].PkScript)
if err != nil {
str := fmt.Sprintf("block %v txOut 1 has wrong pkScript "+
"type", block.Sha())
return ruleError(ErrFirstTxNotCoinbase, str)
}
if len(nullData) < 4 {
str := fmt.Sprintf("block %v txOut 1 has too short nullData "+
"push to contain height", block.Sha())
return ruleError(ErrFirstTxNotCoinbase, str)
}
// Check the height and ensure it is correct.
cbHeight := binary.LittleEndian.Uint32(nullData[0:4])
if cbHeight != uint32(blockHeight) {
prevBlock := block.MsgBlock().Header.PrevBlock
str := fmt.Sprintf("block %v txOut 1 has wrong height in "+
"coinbase; want %v, got %v; prevBlock %v, header height %v",
block.Sha(), blockHeight, cbHeight, prevBlock,
block.MsgBlock().Header.Height)
return ruleError(ErrCoinbaseHeight, str)
}
return nil
}
示例9: connectTransactions
// connectTransactions updates the view by adding all new utxos created by all
// of the transactions in the passed block, marking all utxos the transactions
// spend as spent, and setting the best hash for the view to the passed block.
// In addition, when the 'stxos' argument is not nil, it will be updated to
// append an entry for each spent txout.
func (b *BlockChain) connectTransactions(view *UtxoViewpoint, block *dcrutil.Block,
parent *dcrutil.Block, stxos *[]spentTxOut) error {
regularTxTreeValid := dcrutil.IsFlagSet16(block.MsgBlock().Header.VoteBits,
dcrutil.BlockValid)
thisNodeStakeViewpoint := ViewpointPrevInvalidStake
if regularTxTreeValid {
thisNodeStakeViewpoint = ViewpointPrevValidStake
}
if parent != nil && block.Height() != 0 {
view.SetStakeViewpoint(ViewpointPrevValidInitial)
err := view.fetchInputUtxos(b.db, block, parent)
if err != nil {
return err
}
mBlock := block.MsgBlock()
votebits := mBlock.Header.VoteBits
regularTxTreeValid := dcrutil.IsFlagSet16(votebits, dcrutil.BlockValid)
if regularTxTreeValid {
for i, tx := range parent.Transactions() {
err := view.connectTransaction(tx, parent.Height(), uint32(i),
stxos)
if err != nil {
return err
}
}
}
}
for i, stx := range block.STransactions() {
view.SetStakeViewpoint(thisNodeStakeViewpoint)
err := view.fetchInputUtxos(b.db, block, parent)
if err != nil {
return err
}
err = view.connectTransaction(stx, block.Height(), uint32(i), stxos)
if err != nil {
return err
}
}
// Update the best hash for view to include this block since all of its
// transactions have been connected.
view.SetBestHash(block.Sha())
return nil
}
示例10: NewMerkleBlock
// NewMerkleBlock returns a new *wire.MsgMerkleBlock and an array of the matched
// transaction hashes based on the passed block and filter.
func NewMerkleBlock(block *dcrutil.Block, filter *Filter) (*wire.MsgMerkleBlock, []*chainhash.Hash) {
numTx := uint32(len(block.Transactions()))
mBlock := merkleBlock{
numTx: numTx,
allHashes: make([]*chainhash.Hash, 0, numTx),
matchedBits: make([]byte, 0, numTx),
}
// Find and keep track of any transactions that match the filter.
var matchedHashes []*chainhash.Hash
for _, tx := range block.Transactions() {
if filter.MatchTxAndUpdate(tx) {
mBlock.matchedBits = append(mBlock.matchedBits, 0x01)
matchedHashes = append(matchedHashes, tx.Sha())
} else {
mBlock.matchedBits = append(mBlock.matchedBits, 0x00)
}
mBlock.allHashes = append(mBlock.allHashes, tx.Sha())
}
// Calculate the number of merkle branches (height) in the tree.
height := uint32(0)
for mBlock.calcTreeWidth(height) > 1 {
height++
}
// Build the depth-first partial merkle tree.
mBlock.traverseAndBuild(height, 0)
// Create and return the merkle block.
msgMerkleBlock := wire.MsgMerkleBlock{
Header: block.MsgBlock().Header,
Transactions: uint32(mBlock.numTx),
Hashes: make([]*chainhash.Hash, 0, len(mBlock.finalHashes)),
Flags: make([]byte, (len(mBlock.bits)+7)/8),
}
for _, sha := range mBlock.finalHashes {
msgMerkleBlock.AddTxHash(sha)
}
for i := uint32(0); i < uint32(len(mBlock.bits)); i++ {
msgMerkleBlock.Flags[i/8] |= mBlock.bits[i] << (i % 8)
}
return &msgMerkleBlock, matchedHashes
}
示例11: dbRemoveTxIndexEntries
// dbRemoveTxIndexEntries uses an existing database transaction to remove the
// latest transaction entry for every transaction in the passed block.
func dbRemoveTxIndexEntries(dbTx database.Tx, block, parent *dcrutil.Block) error {
regularTxTreeValid := dcrutil.IsFlagSet16(block.MsgBlock().Header.VoteBits,
dcrutil.BlockValid)
if regularTxTreeValid {
for _, tx := range parent.Transactions() {
txSha := tx.Sha()
err := dbRemoveTxIndexEntry(dbTx, *txSha)
if err != nil {
return err
}
}
}
for _, tx := range block.STransactions() {
txSha := tx.Sha()
err := dbRemoveTxIndexEntry(dbTx, *txSha)
if err != nil {
return err
}
}
return nil
}
示例12: dbIndexConnectBlock
// dbIndexConnectBlock adds all of the index entries associated with the
// given block using the provided indexer and updates the tip of the indexer
// accordingly. An error will be returned if the current tip for the indexer is
// not the previous block for the passed block.
func dbIndexConnectBlock(dbTx database.Tx, indexer Indexer, block, parent *dcrutil.Block, view *blockchain.UtxoViewpoint) error {
// Assert that the block being connected properly connects to the
// current tip of the index.
idxKey := indexer.Key()
curTipHash, _, err := dbFetchIndexerTip(dbTx, idxKey)
if err != nil {
return err
}
if !curTipHash.IsEqual(&block.MsgBlock().Header.PrevBlock) {
return AssertError(fmt.Sprintf("dbIndexConnectBlock must be "+
"called with a block that extends the current index "+
"tip (%s, tip %s, block %s)", indexer.Name(),
curTipHash, block.Sha()))
}
// Notify the indexer with the connected block so it can index it.
if err := indexer.ConnectBlock(dbTx, block, parent, view); err != nil {
return err
}
// Update the current index tip.
return dbPutIndexerTip(dbTx, idxKey, block.Sha(), uint32(block.Height()))
}
示例13: CalculateAddedSubsidy
// CalculateAddedSubsidy calculates the amount of subsidy added by a block
// and its parent. The blocks passed to this function MUST be valid blocks
// that have already been confirmed to abide by the consensus rules of the
// network, or the function might panic.
func CalculateAddedSubsidy(block, parent *dcrutil.Block) int64 {
var subsidy int64
regularTxTreeValid := dcrutil.IsFlagSet16(block.MsgBlock().Header.VoteBits,
dcrutil.BlockValid)
if regularTxTreeValid {
subsidy += parent.MsgBlock().Transactions[0].TxIn[0].ValueIn
}
for _, stx := range block.MsgBlock().STransactions {
if isSSGen, _ := stake.IsSSGen(stx); isSSGen {
subsidy += stx.TxIn[0].ValueIn
}
}
return subsidy
}
示例14: maybeAcceptBlock
// maybeAcceptBlock potentially accepts a block into the memory block chain.
// It performs several validation checks which depend on its position within
// the block chain before adding it. The block is expected to have already gone
// through ProcessBlock before calling this function with it.
//
// The flags modify the behavior of this function as follows:
// - BFDryRun: The memory chain index will not be pruned and no accept
// notification will be sent since the block is not being accepted.
func (b *BlockChain) maybeAcceptBlock(block *dcrutil.Block,
flags BehaviorFlags) (bool, error) {
dryRun := flags&BFDryRun == BFDryRun
// Get a block node for the block previous to this one. Will be nil
// if this is the genesis block.
prevNode, err := b.getPrevNodeFromBlock(block)
if err != nil {
log.Debugf("getPrevNodeFromBlock: %v", err)
return false, err
}
// The height of this block is one more than the referenced previous
// block.
blockHeight := int64(0)
if prevNode != nil {
blockHeight = prevNode.height + 1
}
block.SetHeight(blockHeight)
// The block must pass all of the validation rules which depend on the
// position of the block within the block chain.
err = b.checkBlockContext(block, prevNode, flags)
if err != nil {
return false, err
}
// Prune block nodes which are no longer needed before creating
// a new node.
if !dryRun {
err = b.pruneBlockNodes()
if err != nil {
return false, err
}
}
// Create a new block node for the block and add it to the in-memory
// block chain (could be either a side chain or the main chain).
blockHeader := &block.MsgBlock().Header
var voteBitsStake []uint16
for _, stx := range block.STransactions() {
if is, _ := stake.IsSSGen(stx); is {
vb := stake.GetSSGenVoteBits(stx)
voteBitsStake = append(voteBitsStake, vb)
}
}
newNode := newBlockNode(blockHeader, block.Sha(), blockHeight, voteBitsStake)
if prevNode != nil {
newNode.parent = prevNode
newNode.height = blockHeight
newNode.workSum.Add(prevNode.workSum, newNode.workSum)
}
// Connect the passed block to the chain while respecting proper chain
// selection according to the chain with the most proof of work. This
// also handles validation of the transaction scripts.
var onMainChain bool
onMainChain, err = b.connectBestChain(newNode, block, flags)
if err != nil {
return false, err
}
// Notify the caller that the new block was accepted into the block
// chain. The caller would typically want to react by relaying the
// inventory to other peers.
if !dryRun {
b.sendNotification(NTBlockAccepted,
&BlockAcceptedNtfnsData{onMainChain, block})
}
return onMainChain, nil
}
示例15: insertBlock
// insertBlock is the internal function which implements the public
// InsertBlock. See the comment for InsertBlock for more details.
//
// This function MUST be called with the tmdb lock held (for writes).
func (tmdb *TicketDB) insertBlock(block *dcrutil.Block) (SStxMemMap,
SStxMemMap, SStxMemMap, error) {
height := block.Height()
if height < tmdb.StakeEnabledHeight {
return nil, nil, nil, nil
}
// Sanity check: Does the number of tickets in ticketMap equal the number
// of tickets indicated in the header?
poolSizeBlock := int(block.MsgBlock().Header.PoolSize)
poolSize := 0
for i := 0; i < BucketsSize; i++ {
poolSize += len(tmdb.maps.ticketMap[i])
}
if poolSize != poolSizeBlock {
return nil, nil, nil, fmt.Errorf("ticketpoolsize in block %v not "+
"equal to the calculated ticketpoolsize, indicating database "+
"corruption (got %v, want %v)",
block.Sha(),
poolSizeBlock,
poolSize)
}
// Create the block in the spentTicketMap.
tmdb.maybeInsertBlock(block.Height())
// Iterate through all the SSGen (vote) tx in the block and add them to
// a map of tickets that were actually used. The rest of the tickets in
// the buckets were then considered missed --> missedTicketMap.
// Note that it doesn't really matter what value you set usedTickets to,
// it's just a map of tickets that were actually used in the block. It
// would probably be more efficient to use an array.
usedTickets := make(map[chainhash.Hash]struct{})
spendingHashes := make(map[chainhash.Hash]chainhash.Hash)
revocations := make(map[chainhash.Hash]struct{})
for _, staketx := range block.STransactions() {
if is, _ := IsSSGen(staketx); is {
msgTx := staketx.MsgTx()
sstxIn := msgTx.TxIn[1] // sstx input
sstxHash := sstxIn.PreviousOutPoint.Hash
usedTickets[sstxHash] = struct{}{}
spendingHashes[sstxHash] = *staketx.Sha()
}
if is, _ := IsSSRtx(staketx); is {
msgTx := staketx.MsgTx()
sstxIn := msgTx.TxIn[0] // sstx input
sstxHash := sstxIn.PreviousOutPoint.Hash
revocations[sstxHash] = struct{}{}
}
}
// Spend or miss all the necessary tickets and do some sanity checks.
parentBlock, err := tmdb.database.FetchBlockBySha(
&block.MsgBlock().Header.PrevBlock)
if err != nil {
return nil, nil, nil, err
}
spentAndMissedTickets, err := tmdb.spendTickets(parentBlock,
usedTickets,
spendingHashes)
if err != nil {
return nil, nil, nil, err
}
// Expire all old tickets, and stick them into the spent and missed ticket
// map too.
expiredTickets, err := tmdb.expireTickets(height)
if err != nil {
return nil, nil, nil, err
}
if len(expiredTickets) > 0 && len(spentAndMissedTickets) == 0 {
return nil, nil, nil, fmt.Errorf("tried to expire tickets before " +
"stake validation height! TicketExpiry may be too small")
}
if len(expiredTickets) > 0 {
for hash, ticket := range expiredTickets {
spentAndMissedTickets[hash] = ticket
}
}
revokedTickets, err := tmdb.revokeTickets(revocations)
if err != nil {
return nil, nil, nil, err
}
newTickets, err := tmdb.pushMatureTicketsAtHeight(block.Height())
if err != nil {
return nil, nil, nil, err
}
log.Debugf("Connected block %v (height %v) to the ticket database",
//.........这里部分代码省略.........