mirror of
https://github.com/FlipsideCrypto/dcrd.git
synced 2026-02-06 10:56:47 +00:00
The legacy ticket database, which was GOB serialized and stored on shut down, has been removed. Ticket state information is now held in a stake node, which acts as a modularized "black box" to contain all information about the state of the stake system. Stake nodes are now a component of the blockchain blockNode struct, and are updated with them. Stake nodes, like their internal treap primitives, are immutable objects that are created with their connect and disconnect node functions. The blockchain database now stores all information about the stake state of the best node in the block database. The blockchain makes the assumption that the stake state of the best node is known at any given time. If the states of former blocks or sidechains must be evaluated, this can be achieved by iterating backwards along the blockchain from the best node, and then connecting stake nodes iteratively if necessary. Performance improvements with this new module are dramatic. The long delays on start up and shut down are removed. Blockchain synchronization time is improved approximately 5-10x on the mainnet chain. The state of the database is atomic, so unexpected shut downs should no longer have the ability to disrupt the chain state. An upgrade path has been added for version 1 blockchain databases. Users with this blockchain database will automatically update when they start their clients.
112 lines
4.0 KiB
Go
112 lines
4.0 KiB
Go
// Copyright (c) 2014-2016 The btcsuite developers
|
|
// Copyright (c) 2015-2016 The Decred developers
|
|
// Use of this source code is governed by an ISC
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package blockchain_test
|
|
|
|
import (
|
|
"fmt"
|
|
"math/big"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/decred/dcrd/blockchain"
|
|
"github.com/decred/dcrd/chaincfg"
|
|
"github.com/decred/dcrd/database"
|
|
_ "github.com/decred/dcrd/database/ffldb"
|
|
"github.com/decred/dcrutil"
|
|
)
|
|
|
|
// This example demonstrates how to create a new chain instance and use
|
|
// ProcessBlock to attempt to attempt add a block to the chain. As the package
|
|
// overview documentation describes, this includes all of the Decred consensus
|
|
// rules. This example intentionally attempts to insert a duplicate genesis
|
|
// block to illustrate how an invalid block is handled.
|
|
func ExampleBlockChain_ProcessBlock() {
|
|
// Create a new database to store the accepted blocks into. Typically
|
|
// this would be opening an existing database and would not be deleting
|
|
// and creating a new database like this, but it is done here so this is
|
|
// a complete working example and does not leave temporary files laying
|
|
// around.
|
|
dbPath := filepath.Join(os.TempDir(), "exampleprocessblock")
|
|
_ = os.RemoveAll(dbPath)
|
|
db, err := database.Create("ffldb", dbPath, chaincfg.MainNetParams.Net)
|
|
if err != nil {
|
|
fmt.Printf("Failed to create database: %v\n", err)
|
|
return
|
|
}
|
|
defer os.RemoveAll(dbPath)
|
|
defer db.Close()
|
|
|
|
// Create a new BlockChain instance using the underlying database for
|
|
// the main bitcoin network. This example does not demonstrate some
|
|
// of the other available configuration options such as specifying a
|
|
// notification callback and signature cache.
|
|
chain, err := blockchain.New(&blockchain.Config{
|
|
DB: db,
|
|
ChainParams: &chaincfg.MainNetParams,
|
|
})
|
|
if err != nil {
|
|
fmt.Printf("Failed to create chain instance: %v\n", err)
|
|
return
|
|
}
|
|
|
|
// Create a new median time source that is required by the upcoming
|
|
// call to ProcessBlock. Ordinarily this would also add time values
|
|
// obtained from other peers on the network so the local time is
|
|
// adjusted to be in agreement with other peers.
|
|
timeSource := blockchain.NewMedianTime()
|
|
|
|
// Create a new BlockChain instance using the underlying database for
|
|
// the main bitcoin network. This example does not demonstrate some
|
|
// of the other available configuration options such as specifying a
|
|
// notification callback and signature cache.
|
|
genesisBlock := dcrutil.NewBlock(chaincfg.MainNetParams.GenesisBlock)
|
|
_, isOrphan, err := chain.ProcessBlock(genesisBlock, timeSource, blockchain.BFNone)
|
|
if err != nil {
|
|
fmt.Printf("Failed to create chain instance: %v\n", err)
|
|
return
|
|
}
|
|
fmt.Printf("Block accepted. Is it an orphan?: %v", isOrphan)
|
|
|
|
// This output is dependent on the genesis block, and needs to be
|
|
// updated if the mainnet genesis block is updated.
|
|
// Output:
|
|
// Failed to process block: already have block 267a53b5ee86c24a48ec37aee4f4e7c0c4004892b7259e695e9f5b321f1ab9d2
|
|
}
|
|
|
|
// This example demonstrates how to convert the compact "bits" in a block header
|
|
// which represent the target difficulty to a big integer and display it using
|
|
// the typical hex notation.
|
|
func ExampleCompactToBig() {
|
|
// Convert the bits from block 300000 in the main Decred block chain.
|
|
bits := uint32(419465580)
|
|
targetDifficulty := blockchain.CompactToBig(bits)
|
|
|
|
// Display it in hex.
|
|
fmt.Printf("%064x\n", targetDifficulty.Bytes())
|
|
|
|
// Output:
|
|
// 0000000000000000896c00000000000000000000000000000000000000000000
|
|
}
|
|
|
|
// This example demonstrates how to convert a target difficulty into the compact
|
|
// "bits" in a block header which represent that target difficulty .
|
|
func ExampleBigToCompact() {
|
|
// Convert the target difficulty from block 300000 in the main block
|
|
// chain to compact form.
|
|
t := "0000000000000000896c00000000000000000000000000000000000000000000"
|
|
targetDifficulty, success := new(big.Int).SetString(t, 16)
|
|
if !success {
|
|
fmt.Println("invalid target difficulty")
|
|
return
|
|
}
|
|
bits := blockchain.BigToCompact(targetDifficulty)
|
|
|
|
fmt.Println(bits)
|
|
|
|
// Output:
|
|
// 419465580
|
|
}
|