dcrd/database/example_test.go

178 lines
5.4 KiB
Go
Raw Permalink Normal View History

// Copyright (c) 2015-2016 The btcsuite developers
// Copyright (c) 2016-2019 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package database_test
import (
"bytes"
"fmt"
"os"
"path/filepath"
"github.com/decred/dcrd/chaincfg/v2"
2019-07-22 07:20:07 +00:00
"github.com/decred/dcrd/database/v2"
_ "github.com/decred/dcrd/database/v2/ffldb"
"github.com/decred/dcrd/dcrutil/v2"
"github.com/decred/dcrd/wire"
)
// This example demonstrates creating a new database.
func ExampleCreate() {
// This example assumes the ffldb driver is imported.
//
2014-07-08 13:50:12 +00:00
// import (
// "github.com/decred/dcrd/database2"
main: Update to use all new major module versions. This updates all code in the main module to use the latest major modules versions to pull in the latest updates. A more general high level overview of the changes is provided below, however, there is one semantic change worth calling out independently. The verifymessage RPC will now return an error when provided with an address that is not for the current active network and the RPC server version has been bumped accordingly. Previously, it would return false which indicated the signature is invalid, even when the provided signature was actually valid for the other network. Said behavior was not really incorrect since the address, signature, and message combination is in fact invalid for the current active network, however, that result could be somewhat misleading since a false result could easily be interpreted to mean the signature is actually invalid altogether which is distinct from the case of the address being for a different network. Therefore, it is preferable to explicitly return an error in the case of an address on the wrong network to cleanly separate these cases. The following is a high level overview of the changes: - Replace all calls to removed blockchain merkle root, pow, subsidy, and coinbase funcs with their standalone module equivalents - Introduce a new local func named calcTxTreeMerkleRoot that accepts dcrutil.Tx as before and defers to the new standalone func - Update block locator handling to match the new signature required by the peer/v2 module - Introduce a new local func named chainBlockLocatorToHashes which performs the necessary conversion - Update all references to old v1 chaincfg params global instances to use the new v2 functions - Modify all cases that parse addresses to provide the now required current network params - Include address params with the wsClientFilter - Replace removed v1 chaincfg constants with local constants - Create subsidy cache during server init and pass it to the relevant subsystems - blockManagerConfig - BlkTmplGenerator - rpcServer - VotingWallet - Update mining code that creates the block one coinbase transaction to create the output scripts as defined in the v2 params - Replace old v2 dcrjson constant references with new types module - Fix various comment typos - Update fees module to use the latest major module versions and bump it v2
2019-08-13 15:50:53 +00:00
// _ "github.com/decred/dcrd/database/v2/ffldb"
2014-07-08 13:50:12 +00:00
// )
// Create a database and schedule it to be closed and removed on exit.
// Typically you wouldn't want to remove the database right away like
// this, nor put it in the temp directory, but it's done here to ensure
// the example cleans up after itself.
dbPath := filepath.Join(os.TempDir(), "examplecreate-v2")
db, err := database.Create("ffldb", dbPath, wire.MainNet)
if err != nil {
fmt.Println(err)
return
}
defer os.RemoveAll(dbPath)
defer db.Close()
// Output:
}
// This example demonstrates creating a new database and using a managed
// read-write transaction to store and retrieve metadata.
func Example_basicUsage() {
// This example assumes the ffldb driver is imported.
//
// import (
// "github.com/decred/dcrd/database2"
2019-07-22 07:20:07 +00:00
// _ "github.com/decred/dcrd/database/v2/ffldb"
// )
// Create a database and schedule it to be closed and removed on exit.
// Typically you wouldn't want to remove the database right away like
// this, nor put it in the temp directory, but it's done here to ensure
// the example cleans up after itself.
dbPath := filepath.Join(os.TempDir(), "exampleusage-v2")
db, err := database.Create("ffldb", dbPath, wire.MainNet)
if err != nil {
fmt.Println(err)
return
}
defer os.RemoveAll(dbPath)
defer db.Close()
// Use the Update function of the database to perform a managed
// read-write transaction. The transaction will automatically be rolled
// back if the supplied inner function returns a non-nil error.
err = db.Update(func(tx database.Tx) error {
// Store a key/value pair directly in the metadata bucket.
// Typically a nested bucket would be used for a given feature,
// but this example is using the metadata bucket directly for
// simplicity.
key := []byte("mykey")
value := []byte("myvalue")
if err := tx.Metadata().Put(key, value); err != nil {
return err
}
// Read the key back and ensure it matches.
if !bytes.Equal(tx.Metadata().Get(key), value) {
return fmt.Errorf("unexpected value for key '%s'", key)
}
2014-07-08 14:10:14 +00:00
// Create a new nested bucket under the metadata bucket.
nestedBucketKey := []byte("mybucket")
nestedBucket, err := tx.Metadata().CreateBucket(nestedBucketKey)
if err != nil {
return err
}
// The key from above that was set in the metadata bucket does
// not exist in this new nested bucket.
if nestedBucket.Get(key) != nil {
return fmt.Errorf("key '%s' is not expected nil", key)
}
2014-07-08 14:10:14 +00:00
return nil
})
2014-07-08 14:10:14 +00:00
if err != nil {
fmt.Println(err)
return
2014-07-08 14:10:14 +00:00
}
// Output:
2014-07-08 14:10:14 +00:00
}
// This example demonstrates creating a new database, using a managed read-write
// transaction to store a block, and using a managed read-only transaction to
// fetch the block.
func Example_blockStorageAndRetrieval() {
// This example assumes the ffldb driver is imported.
//
// import (
// "github.com/decred/dcrd/database2"
2019-07-22 07:20:07 +00:00
// _ "github.com/decred/dcrd/database/v2/ffldb"
// )
// Create a database and schedule it to be closed and removed on exit.
// Typically you wouldn't want to remove the database right away like
// this, nor put it in the temp directory, but it's done here to ensure
// the example cleans up after itself.
dbPath := filepath.Join(os.TempDir(), "exampleblkstorage-v2")
db, err := database.Create("ffldb", dbPath, wire.MainNet)
2014-07-08 14:10:14 +00:00
if err != nil {
fmt.Println(err)
return
}
defer os.RemoveAll(dbPath)
2014-07-08 14:10:14 +00:00
defer db.Close()
// Use the Update function of the database to perform a managed
// read-write transaction and store a genesis block in the database as
// and example.
mainNetParams := chaincfg.MainNetParams()
err = db.Update(func(tx database.Tx) error {
return tx.StoreBlock(dcrutil.NewBlock(mainNetParams.GenesisBlock))
})
if err != nil {
fmt.Println(err)
return
}
// Use the View function of the database to perform a managed read-only
// transaction and fetch the block stored above.
var loadedBlockBytes []byte
err = db.Update(func(tx database.Tx) error {
blockBytes, err := tx.FetchBlock(&mainNetParams.GenesisHash)
if err != nil {
return err
}
// As documented, all data fetched from the database is only
// valid during a database transaction in order to support
// zero-copy backends. Thus, make a copy of the data so it
// can be used outside of the transaction.
loadedBlockBytes = make([]byte, len(blockBytes))
copy(loadedBlockBytes, blockBytes)
return nil
})
2014-07-08 14:10:14 +00:00
if err != nil {
fmt.Println(err)
return
}
// Typically at this point, the block could be deserialized via the
// wire.MsgBlock.Deserialize function or used in its serialized form
// depending on need. However, for this example, just display the
// number of serialized bytes to show it was loaded as expected.
fmt.Printf("Serialized block size: %d bytes\n", len(loadedBlockBytes))
2014-07-08 14:10:14 +00:00
// Output:
// Serialized block size: 300 bytes
2014-07-08 14:10:14 +00:00
}