本文整理汇总了Golang中github.com/decred/dcrwallet/walletdb.ReadWriteTx.ReadWriteBucket方法的典型用法代码示例。如果您正苦于以下问题:Golang ReadWriteTx.ReadWriteBucket方法的具体用法?Golang ReadWriteTx.ReadWriteBucket怎么用?Golang ReadWriteTx.ReadWriteBucket使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类github.com/decred/dcrwallet/walletdb.ReadWriteTx
的用法示例。
在下文中一共展示了ReadWriteTx.ReadWriteBucket方法的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: handleMissedTickets
// handleMissedTickets receives a list of hashes and some block information
// and submits it to the wstakemgr to handle SSRtx production.
func (w *Wallet) handleMissedTickets(dbtx walletdb.ReadWriteTx, blockHash *chainhash.Hash,
blockHeight int64, tickets []*chainhash.Hash) error {
stakemgrNs := dbtx.ReadWriteBucket(wstakemgrNamespaceKey)
addrmgrNs := dbtx.ReadBucket(waddrmgrNamespaceKey)
if !w.StakeMiningEnabled {
return nil
}
if blockHeight >= w.chainParams.StakeValidationHeight+1 &&
w.StakeMiningEnabled {
ntfns, err := w.StakeMgr.HandleMissedTicketsNtfn(stakemgrNs, addrmgrNs,
blockHash, blockHeight, tickets, w.AllowHighFees)
if ntfns != nil {
// Send notifications for newly created revocations by the RPC.
for _, ntfn := range ntfns {
if ntfn != nil {
// Inform the console that we've revoked our ticket.
log.Infof("Revoked missed ticket %v (tx hash: %v)",
ntfn.SStxIn,
ntfn.TxHash)
}
}
}
return err
}
return nil
}
示例2: disconnectBlock
// disconnectBlock handles a chain server reorganize by rolling back all
// block history from the reorged block for a wallet in-sync with the chain
// server.
func (w *Wallet) disconnectBlock(dbtx walletdb.ReadWriteTx, b wtxmgr.BlockMeta) error {
addrmgrNs := dbtx.ReadWriteBucket(waddrmgrNamespaceKey)
txmgrNs := dbtx.ReadWriteBucket(wtxmgrNamespaceKey)
if !w.ChainSynced() {
return nil
}
bs := waddrmgr.BlockStamp{
Height: b.Height,
Hash: b.Hash,
}
log.Infof("Disconnecting block %v, height %v", bs.Hash, bs.Height)
// Disconnect the last seen block from the manager if it matches the
// removed block.
err := w.TxStore.Rollback(txmgrNs, addrmgrNs, b.Height)
if err != nil {
return err
}
prev, err := w.TxStore.GetBlockHash(txmgrNs, b.Height-1)
if err != nil {
return err
}
prevBlock := &waddrmgr.BlockStamp{Hash: prev, Height: b.Height - 1}
err = w.Manager.SetSyncedTo(addrmgrNs, prevBlock)
if err != nil {
return err
}
// Notify interested clients of the disconnected block.
w.NtfnServer.notifyDetachedBlock(&b.Hash)
return nil
}
示例3: extendMainChain
func (w *Wallet) extendMainChain(dbtx walletdb.ReadWriteTx, block *wtxmgr.BlockHeaderData, transactions [][]byte) error {
txmgrNs := dbtx.ReadWriteBucket(wtxmgrNamespaceKey)
log.Infof("Connecting block %v, height %v", block.BlockHash,
block.SerializedHeader.Height())
err := w.TxStore.ExtendMainChain(txmgrNs, block)
if err != nil {
return err
}
// Notify interested clients of the connected block.
var header wire.BlockHeader
header.Deserialize(bytes.NewReader(block.SerializedHeader[:]))
w.NtfnServer.notifyAttachedBlock(dbtx, &header, &block.BlockHash)
blockMeta, err := w.TxStore.GetBlockMetaForHash(txmgrNs, &block.BlockHash)
if err != nil {
return err
}
for _, serializedTx := range transactions {
err = w.processTransaction(dbtx, serializedTx,
&block.SerializedHeader, &blockMeta)
if err != nil {
return err
}
}
return nil
}
示例4: handleWinningTickets
// handleWinningTickets receives a list of hashes and some block information
// and submits it to the wstakemgr to handle SSGen production.
func (w *Wallet) handleWinningTickets(dbtx walletdb.ReadWriteTx, blockHash *chainhash.Hash,
blockHeight int64, tickets []*chainhash.Hash) error {
addrmgrNs := dbtx.ReadBucket(waddrmgrNamespaceKey)
stakemgrNs := dbtx.ReadWriteBucket(wstakemgrNamespaceKey)
txmgrNs := dbtx.ReadBucket(wtxmgrNamespaceKey)
topHash, _ := w.TxStore.MainChainTip(txmgrNs)
// Even if stake voting is disabled, we should still store eligible
// tickets for the current top block.
// TODO The behavior of this is not quite right if tons of blocks
// are coming in quickly, because the transaction store will end up
// out of sync with the voting channel here. This should probably
// be fixed somehow, but this should be stable for networks that
// are voting at normal block speeds.
if blockHeight >= w.chainParams.StakeValidationHeight-1 &&
topHash == *blockHash {
w.SetCurrentVotingInfo(blockHash, blockHeight, tickets)
}
if blockHeight >= w.chainParams.StakeValidationHeight-1 &&
w.StakeMiningEnabled {
ntfns, err := w.StakeMgr.HandleWinningTicketsNtfn(
stakemgrNs,
addrmgrNs,
blockHash,
blockHeight,
tickets,
w.VoteBits,
w.AllowHighFees,
)
if ntfns != nil {
// Send notifications for newly created votes by the RPC.
for _, ntfn := range ntfns {
// Inform the console that we've voted, too.
log.Infof("Voted on block %v (height %v) using ticket %v "+
"(vote hash: %v)",
ntfn.BlockHash,
ntfn.Height,
ntfn.SStxIn,
ntfn.TxHash)
}
}
return err
}
return nil
}
示例5: switchToSideChain
// switchToSideChain performs a chain switch, switching the main chain to the
// in-memory side chain. The old side chain becomes the new main chain.
func (w *Wallet) switchToSideChain(dbtx walletdb.ReadWriteTx) error {
addrmgrNs := dbtx.ReadBucket(waddrmgrNamespaceKey)
txmgrNs := dbtx.ReadWriteBucket(wtxmgrNamespaceKey)
sideChain := w.sideChain
if len(sideChain) == 0 {
return errors.New("no side chain to switch to")
}
sideChainForkHeight := sideChain[0].headerData.SerializedHeader.Height()
// Notify detached blocks for each removed block, in reversed order.
_, tipHeight := w.TxStore.MainChainTip(txmgrNs)
for i := tipHeight; i >= sideChainForkHeight; i-- {
hash, err := w.TxStore.GetMainChainBlockHashForHeight(txmgrNs, i)
if err != nil {
return err
}
w.NtfnServer.notifyDetachedBlock(&hash)
}
// Remove blocks on the current main chain that are at or above the
// height of the block that begins the side chain.
err := w.TxStore.Rollback(txmgrNs, addrmgrNs, sideChainForkHeight)
if err != nil {
return err
}
// Extend the main chain with each sidechain block.
for i := range sideChain {
scBlock := &sideChain[i]
err = w.extendMainChain(dbtx, &scBlock.headerData, scBlock.transactions)
if err != nil {
return err
}
}
return nil
}
示例6: addRelevantTx
func (w *Wallet) addRelevantTx(dbtx walletdb.ReadWriteTx, rec *wtxmgr.TxRecord,
block *wtxmgr.BlockMeta) error {
addrmgrNs := dbtx.ReadWriteBucket(waddrmgrNamespaceKey)
stakemgrNs := dbtx.ReadWriteBucket(wstakemgrNamespaceKey)
txmgrNs := dbtx.ReadWriteBucket(wtxmgrNamespaceKey)
// At the moment all notified transactions are assumed to actually be
// relevant. This assumption will not hold true when SPV support is
// added, but until then, simply insert the transaction because there
// should either be one or more relevant inputs or outputs.
//
// TODO This function is pretty bad corruption wise, it's very easy
// to corrupt the wallet if you ctrl+c while in this function. This
// needs desperate refactoring.
tx := dcrutil.NewTx(&rec.MsgTx)
txHash := rec.Hash
// Handle incoming SStx; store them in the stake manager if we own
// the OP_SSTX tagged out, except if we're operating as a stake pool
// server. In that case, additionally consider the first commitment
// output as well.
if is, _ := stake.IsSStx(&rec.MsgTx); is {
// Errors don't matter here. If addrs is nil, the range below
// does nothing.
txOut := tx.MsgTx().TxOut[0]
_, addrs, _, _ := txscript.ExtractPkScriptAddrs(txOut.Version,
txOut.PkScript, w.chainParams)
insert := false
for _, addr := range addrs {
_, err := w.Manager.Address(addrmgrNs, addr)
if err == nil {
// We own the voting output pubkey or script and we're
// not operating as a stake pool, so simply insert this
// ticket now.
if !w.stakePoolEnabled {
insert = true
break
} else {
// We are operating as a stake pool. The below
// function will ONLY add the ticket into the
// stake pool if it has been found within a
// block.
if block == nil {
break
}
valid, errEval := w.evaluateStakePoolTicket(rec, block,
addr)
if valid {
// Be sure to insert this into the user's stake
// pool entry into the stake manager.
poolTicket := &wstakemgr.PoolTicket{
Ticket: txHash,
HeightTicket: uint32(block.Height),
Status: wstakemgr.TSImmatureOrLive,
}
errUpdate := w.StakeMgr.UpdateStakePoolUserTickets(
stakemgrNs, addrmgrNs, addr, poolTicket)
if errUpdate != nil {
log.Warnf("Failed to insert stake pool "+
"user ticket: %s", err.Error())
}
log.Debugf("Inserted stake pool ticket %v for user %v "+
"into the stake store database", txHash, addr)
insert = true
break
}
// Log errors if there were any. At this point the ticket
// must be invalid, so insert it into the list of invalid
// user tickets.
if errEval != nil {
log.Warnf("Ticket %v failed ticket evaluation for "+
"the stake pool: %s", rec.Hash, err.Error())
}
errUpdate := w.StakeMgr.UpdateStakePoolUserInvalTickets(
stakemgrNs, addr, &rec.Hash)
if errUpdate != nil {
log.Warnf("Failed to update pool user %v with "+
"invalid ticket %v", addr.EncodeAddress(),
rec.Hash)
}
}
}
}
if insert {
err := w.StakeMgr.InsertSStx(stakemgrNs, tx, w.VoteBits)
if err != nil {
log.Errorf("Failed to insert SStx %v"+
"into the stake store.", tx.Sha())
}
}
}
// Handle incoming SSGen; store them if we own
//.........这里部分代码省略.........
示例7: connectBlock
// connectBlock handles a chain server notification by marking a wallet
// that's currently in-sync with the chain server as being synced up to
// the passed block.
func (w *Wallet) connectBlock(dbtx walletdb.ReadWriteTx, b wtxmgr.BlockMeta) error {
addrmgrNs := dbtx.ReadWriteBucket(waddrmgrNamespaceKey)
txmgrNs := dbtx.ReadWriteBucket(wtxmgrNamespaceKey)
chainClient, err := w.requireChainClient()
if err != nil {
return err
}
bs := waddrmgr.BlockStamp{
Height: b.Height,
Hash: b.Hash,
}
log.Infof("Connecting block %v, height %v", bs.Hash, bs.Height)
err = w.Manager.SetSyncedTo(addrmgrNs, &bs)
if err != nil {
return err
}
// Handle automatic ticket purchasing if enabled. This function should
// not error due to an error purchasing tickets (several tickets may be
// have been purhcased and successfully published, as well as addresses
// created and used), so just log it instead.
err = w.handleTicketPurchases(dbtx)
switch err.(type) {
case nil:
case txauthor.InsufficientFundsError:
log.Debugf("Insufficient funds to auto-purchase maximum number " +
"of tickets")
default:
log.Errorf("Failed to perform automatic picket purchasing: %v", err)
}
// Insert the block if we haven't already through a relevant tx.
err = w.TxStore.InsertBlock(txmgrNs, &b)
if err != nil {
err = fmt.Errorf("Couldn't insert block %v into database: %v",
b.Hash, err)
return err
}
// Rollback testing for simulation network, if enabled.
if b.Height < rollbackTestHeight && w.rollbackTesting {
dbd, err := w.TxStore.DatabaseDump(txmgrNs, addrmgrNs, b.Height, nil)
if err != nil {
panicStr := fmt.Sprintf("Failed to dump database at connection "+
"of block %v (height %v): %v",
b.Hash,
b.Height,
err.Error())
panic(panicStr)
}
if dbd.OneConfBalance != dbd.OneConfCalcBalance {
log.Warnf("Balance calculations incongruent. The spendable "+
"balance was %v, but the recalculated spendable balance "+
"was %v",
dbd.OneConfBalance,
dbd.OneConfCalcBalance)
}
w.rollbackBlockDB[uint32(b.Height)] = dbd
}
// We've reached the height to begin the rollback testing from.
if b.Height == rollbackTestHeight && w.rollbackTesting {
log.Infof("Height for rollback testing reached, beginning " +
"database evaluations.")
finalHeight := rollbackTestHeight - rollbackTestDepth
for i := rollbackTestHeight; i >= finalHeight; i-- {
err := w.TxStore.Rollback(txmgrNs, addrmgrNs, int32(i))
if err != nil {
log.Errorf("Error rolling back block at height %v: %v",
i, err)
}
rolledbackDb, err := w.TxStore.DatabaseDump(txmgrNs, addrmgrNs, int32(i-1),
w.rollbackBlockDB[uint32(i-1)].BucketUnminedInputs)
if err != nil {
panicStr := fmt.Sprintf("Failed to dump database at "+
"disconnection of block height %v: %v",
i,
err.Error())
panic(panicStr)
}
is, errStr := w.rollbackBlockDB[uint32(i-1)].Equals(rolledbackDb,
true)
if !is {
log.Errorf("Database incongruencies detected after rolling "+
"back to block %v!\n"+
"%v",
i-1,
errStr)
} else {
log.Infof("Rollback to height %v proceeded without error.",
i-1)
//.........这里部分代码省略.........
示例8: onBlockConnected
// onBlockConnected is the entry point for processing chain server
// blockconnected notifications.
func (w *Wallet) onBlockConnected(dbtx walletdb.ReadWriteTx, serializedBlockHeader []byte, transactions [][]byte) error {
var blockHeader wire.BlockHeader
err := blockHeader.Deserialize(bytes.NewReader(serializedBlockHeader))
if err != nil {
return err
}
block := wtxmgr.BlockHeaderData{BlockHash: blockHeader.BlockSha()}
err = copyHeaderSliceToArray(&block.SerializedHeader, serializedBlockHeader)
if err != nil {
return err
}
w.reorganizingLock.Lock()
reorg, reorgToHash := w.reorganizing, w.reorganizeToHash
w.reorganizingLock.Unlock()
if reorg {
// add to side chain
scBlock := sideChainBlock{
transactions: transactions,
headerData: block,
}
w.sideChain = append(w.sideChain, scBlock)
log.Infof("Adding block %v (height %v) to sidechain",
block.BlockHash, block.SerializedHeader.Height())
if block.BlockHash != reorgToHash {
// Nothing left to do until the later blocks are
// received.
return nil
}
err = w.switchToSideChain(dbtx)
if err != nil {
return err
}
w.sideChain = nil
w.reorganizingLock.Lock()
w.reorganizing = false
w.reorganizingLock.Unlock()
log.Infof("Wallet reorganization to block %v complete", reorgToHash)
} else {
err = w.extendMainChain(dbtx, &block, transactions)
if err != nil {
return err
}
}
height := int32(blockHeader.Height)
// Handle automatic ticket purchasing if enabled. This function should
// not error due to an error purchasing tickets (several tickets may be
// have been purhcased and successfully published, as well as addresses
// created and used), so just log it instead.
err = w.handleTicketPurchases(dbtx, height)
switch err.(type) {
case nil:
case txauthor.InsufficientFundsError:
log.Debugf("Insufficient funds to auto-purchase maximum number " +
"of tickets")
default:
log.Errorf("Failed to perform automatic picket purchasing: %v", err)
}
// Prune all expired transactions and all stake tickets that no longer
// meet the minimum stake difficulty.
txmgrNs := dbtx.ReadWriteBucket(wtxmgrNamespaceKey)
err = w.TxStore.PruneUnconfirmed(txmgrNs, height, blockHeader.SBits)
if err != nil {
log.Errorf("Failed to prune unconfirmed transactions when "+
"connecting block height %v: %s", height, err.Error())
}
return nil
}