github.com/decred/dcrd/blockchain@v1.2.1/example_test.go (about)

     1  // Copyright (c) 2014-2016 The btcsuite developers
     2  // Copyright (c) 2015-2016 The Decred developers
     3  // Use of this source code is governed by an ISC
     4  // license that can be found in the LICENSE file.
     5  
     6  package blockchain_test
     7  
     8  import (
     9  	"fmt"
    10  	"math/big"
    11  	"os"
    12  	"path/filepath"
    13  
    14  	"github.com/decred/dcrd/blockchain"
    15  	"github.com/decred/dcrd/chaincfg"
    16  	"github.com/decred/dcrd/database"
    17  	_ "github.com/decred/dcrd/database/ffldb"
    18  	"github.com/decred/dcrd/dcrutil"
    19  )
    20  
    21  // This example demonstrates how to create a new chain instance and use
    22  // ProcessBlock to attempt to attempt add a block to the chain.  As the package
    23  // overview documentation describes, this includes all of the Decred consensus
    24  // rules.  This example intentionally attempts to insert a duplicate genesis
    25  // block to illustrate how an invalid block is handled.
    26  func ExampleBlockChain_ProcessBlock() {
    27  	// Create a new database to store the accepted blocks into.  Typically
    28  	// this would be opening an existing database and would not be deleting
    29  	// and creating a new database like this, but it is done here so this is
    30  	// a complete working example and does not leave temporary files laying
    31  	// around.
    32  	dbPath := filepath.Join(os.TempDir(), "exampleprocessblock")
    33  	_ = os.RemoveAll(dbPath)
    34  	db, err := database.Create("ffldb", dbPath, chaincfg.MainNetParams.Net)
    35  	if err != nil {
    36  		fmt.Printf("Failed to create database: %v\n", err)
    37  		return
    38  	}
    39  	defer os.RemoveAll(dbPath)
    40  	defer db.Close()
    41  
    42  	// Create a new BlockChain instance using the underlying database for
    43  	// the main bitcoin network.  This example does not demonstrate some
    44  	// of the other available configuration options such as specifying a
    45  	// notification callback and signature cache.  Also, the caller would
    46  	// ordinarily keep a reference to the median time source and add time
    47  	// values obtained from other peers on the network so the local time is
    48  	// adjusted to be in agreement with other peers.
    49  	chain, err := blockchain.New(&blockchain.Config{
    50  		DB:          db,
    51  		ChainParams: &chaincfg.MainNetParams,
    52  		TimeSource:  blockchain.NewMedianTime(),
    53  	})
    54  	if err != nil {
    55  		fmt.Printf("Failed to create chain instance: %v\n", err)
    56  		return
    57  	}
    58  
    59  	// Process a block.  For this example, we are going to intentionally
    60  	// cause an error by trying to process the genesis block which already
    61  	// exists.
    62  	genesisBlock := dcrutil.NewBlock(chaincfg.MainNetParams.GenesisBlock)
    63  	forkLen, isOrphan, err := chain.ProcessBlock(genesisBlock,
    64  		blockchain.BFNone)
    65  	if err != nil {
    66  		fmt.Printf("Failed to create chain instance: %v\n", err)
    67  		return
    68  	}
    69  	isMainChain := !isOrphan && forkLen == 0
    70  	fmt.Printf("Block accepted. Is it on the main chain?: %v", isMainChain)
    71  	fmt.Printf("Block accepted. Is it an orphan?: %v", isOrphan)
    72  
    73  	// This output is dependent on the genesis block, and needs to be
    74  	// updated if the mainnet genesis block is updated.
    75  	// Output:
    76  	// Failed to process block: already have block 267a53b5ee86c24a48ec37aee4f4e7c0c4004892b7259e695e9f5b321f1ab9d2
    77  }
    78  
    79  // This example demonstrates how to convert the compact "bits" in a block header
    80  // which represent the target difficulty to a big integer and display it using
    81  // the typical hex notation.
    82  func ExampleCompactToBig() {
    83  	// Convert the bits from block 300000 in the main Decred block chain.
    84  	bits := uint32(419465580)
    85  	targetDifficulty := blockchain.CompactToBig(bits)
    86  
    87  	// Display it in hex.
    88  	fmt.Printf("%064x\n", targetDifficulty.Bytes())
    89  
    90  	// Output:
    91  	// 0000000000000000896c00000000000000000000000000000000000000000000
    92  }
    93  
    94  // This example demonstrates how to convert a target difficulty into the compact
    95  // "bits" in a block header which represent that target difficulty .
    96  func ExampleBigToCompact() {
    97  	// Convert the target difficulty from block 300000 in the main block
    98  	// chain to compact form.
    99  	t := "0000000000000000896c00000000000000000000000000000000000000000000"
   100  	targetDifficulty, success := new(big.Int).SetString(t, 16)
   101  	if !success {
   102  		fmt.Println("invalid target difficulty")
   103  		return
   104  	}
   105  	bits := blockchain.BigToCompact(targetDifficulty)
   106  
   107  	fmt.Println(bits)
   108  
   109  	// Output:
   110  	// 419465580
   111  }