本文整理匯總了Golang中github.com/NebulousLabs/Sia/types.CalculateCoinbase函數的典型用法代碼示例。如果您正苦於以下問題:Golang CalculateCoinbase函數的具體用法?Golang CalculateCoinbase怎麽用?Golang CalculateCoinbase使用的例子?那麽, 這裏精選的函數代碼示例或許可以為您提供幫助。
在下文中一共展示了CalculateCoinbase函數的15個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: checkSiacoins
// checkSiacoins counts the number of siacoins in the database and verifies
// that it matches the sum of all the coinbases.
func (cs *ConsensusSet) checkSiacoins() error {
// Calculate the number of expected coins in constant time.
deflationBlocks := types.InitialCoinbase - types.MinimumCoinbase
expectedSiacoins := types.CalculateCoinbase(0).Add(types.CalculateCoinbase(cs.height())).Div(types.NewCurrency64(2))
if cs.height() < types.BlockHeight(deflationBlocks) {
expectedSiacoins = expectedSiacoins.Mul(types.NewCurrency64(uint64(cs.height()) + 1))
} else {
expectedSiacoins = expectedSiacoins.Mul(types.NewCurrency64(deflationBlocks + 1))
trailingSiacoins := types.NewCurrency64(uint64(cs.height()) - deflationBlocks).Mul(types.CalculateCoinbase(cs.height()))
expectedSiacoins = expectedSiacoins.Add(trailingSiacoins)
}
totalSiacoins := types.ZeroCurrency
cs.db.forEachSiacoinOutputs(func(scoid types.SiacoinOutputID, sco types.SiacoinOutput) {
totalSiacoins = totalSiacoins.Add(sco.Value)
})
cs.db.forEachFileContracts(func(fcid types.FileContractID, fc types.FileContract) {
var payout types.Currency
for _, output := range fc.ValidProofOutputs {
payout = payout.Add(output.Value)
}
totalSiacoins = totalSiacoins.Add(payout)
})
cs.db.forEachDelayedSiacoinOutputs(func(v types.SiacoinOutputID, dso types.SiacoinOutput) {
totalSiacoins = totalSiacoins.Add(dso.Value)
})
cs.db.forEachSiafundOutputs(func(sfoid types.SiafundOutputID, sfo types.SiafundOutput) {
sfoSiacoins := cs.siafundPool.Sub(sfo.ClaimStart).Div(types.SiafundCount).Mul(sfo.Value)
totalSiacoins = totalSiacoins.Add(sfoSiacoins)
})
if expectedSiacoins.Cmp(totalSiacoins) != 0 {
return errSiacoinMiscount
}
return nil
}
示例2: TestSendSiacoins
// TestSendSiacoins probes the SendSiacoins method of the wallet.
func TestSendSiacoins(t *testing.T) {
if testing.Short() {
t.SkipNow()
}
wt, err := createWalletTester("TestSendSiacoins")
if err != nil {
t.Fatal(err)
}
defer wt.closeWt()
// Get the initial balance - should be 1 block. The unconfirmed balances
// should be 0.
confirmedBal, _, _ := wt.wallet.ConfirmedBalance()
unconfirmedOut, unconfirmedIn := wt.wallet.UnconfirmedBalance()
if confirmedBal.Cmp(types.CalculateCoinbase(1)) != 0 {
t.Error("unexpected confirmed balance")
}
if unconfirmedOut.Cmp(types.ZeroCurrency) != 0 {
t.Error("unconfirmed balance should be 0")
}
if unconfirmedIn.Cmp(types.ZeroCurrency) != 0 {
t.Error("unconfirmed balance should be 0")
}
// Send 5000 hastings. The wallet will automatically add a fee. Outgoing
// unconfirmed siacoins - incoming unconfirmed siacoins should equal 5000 +
// fee.
tpoolFee := types.NewCurrency64(10).Mul(types.SiacoinPrecision)
_, err = wt.wallet.SendSiacoins(types.NewCurrency64(5000), types.UnlockHash{})
if err != nil {
t.Fatal(err)
}
confirmedBal2, _, _ := wt.wallet.ConfirmedBalance()
unconfirmedOut2, unconfirmedIn2 := wt.wallet.UnconfirmedBalance()
if confirmedBal2.Cmp(confirmedBal) != 0 {
t.Error("confirmed balance changed without introduction of blocks")
}
if unconfirmedOut2.Cmp(unconfirmedIn2.Add(types.NewCurrency64(5000)).Add(tpoolFee)) != 0 {
t.Error("sending siacoins appears to be ineffective")
}
// Move the balance into the confirmed set.
b, _ := wt.miner.FindBlock()
err = wt.cs.AcceptBlock(b)
if err != nil {
t.Fatal(err)
}
confirmedBal3, _, _ := wt.wallet.ConfirmedBalance()
unconfirmedOut3, unconfirmedIn3 := wt.wallet.UnconfirmedBalance()
if confirmedBal3.Cmp(confirmedBal2.Add(types.CalculateCoinbase(2)).Sub(types.NewCurrency64(5000)).Sub(tpoolFee)) != 0 {
t.Error("confirmed balance did not adjust to the expected value")
}
if unconfirmedOut3.Cmp(types.ZeroCurrency) != 0 {
t.Error("unconfirmed balance should be 0")
}
if unconfirmedIn3.Cmp(types.ZeroCurrency) != 0 {
t.Error("unconfirmed balance should be 0")
}
}
示例3: testDependentUpdates
// testDependentUpdates adds a parent transaction and a dependent transaction
// to the unconfirmed set. Then the parent transaction is added to the
// confirmed set but the dependent is not. A check is made to see that the
// dependent is still in the unconfirmed set.
func (tpt *tpoolTester) testDependentUpdates() {
// Put two transactions, a parent and a dependent, into the transaction
// pool. Then create a transaction that is in conflict with the parent.
parent := tpt.emptyUnlockTransaction()
dependent := types.Transaction{
SiacoinInputs: []types.SiacoinInput{
types.SiacoinInput{
ParentID: parent.SiacoinOutputID(0),
},
},
MinerFees: []types.Currency{
parent.SiacoinOutputs[0].Value,
},
}
err := tpt.tpool.AcceptTransaction(parent)
if err != nil {
tpt.t.Fatal(err)
}
tpt.tpUpdateWait()
err = tpt.tpool.AcceptTransaction(dependent)
if err != nil {
tpt.t.Fatal(err)
}
tpt.tpUpdateWait()
// Mine a block to put the parent into the confirmed set.
tset := tpt.tpool.TransactionSet()
tset = tset[:len(tset)-1] // strip 'dependent'
target, exists := tpt.cs.ChildTarget(tpt.cs.CurrentBlock().ID())
if !exists {
tpt.t.Fatal("unable to recover child target")
}
block := types.Block{
ParentID: tpt.cs.CurrentBlock().ID(),
Timestamp: types.Timestamp(time.Now().Unix()),
MinerPayouts: []types.SiacoinOutput{
types.SiacoinOutput{Value: types.CalculateCoinbase(tpt.cs.Height() + 1)},
},
Transactions: tset,
}
for {
var found bool
block, found = tpt.miner.SolveBlock(block, target)
if found {
err = tpt.cs.AcceptBlock(block)
if err != nil {
tpt.t.Fatal(err)
}
break
}
}
tpt.csUpdateWait()
// Check that 'parent' and 'dependent' have been removed from the
// transaction set, since conflict has made the confirmed set.
if len(tpt.tpool.TransactionSet()) != 1 {
tpt.t.Error("dependent transaction does not remain unconfirmed after parent has been confirmed:", len(tset))
}
}
示例4: TestBuriedBadFork
// TestBuriedBadFork creates a block with an invalid transaction that's not on
// the longest fork. The consensus set will not validate that block. Then valid
// blocks are added on top of it to make it the longest fork. When it becomes
// the longest fork, all the blocks should be fully validated and thrown out
// because a parent is invalid.
func TestBuriedBadFork(t *testing.T) {
if testing.Short() {
t.SkipNow()
}
t.Parallel()
cst, err := createConsensusSetTester("TestBuriedBadFork")
if err != nil {
t.Fatal(err)
}
defer cst.Close()
pb := cst.cs.dbCurrentProcessedBlock()
// Create a bad block that builds on a parent, so that it is part of not
// the longest fork.
badBlock := types.Block{
ParentID: pb.Block.ParentID,
Timestamp: types.CurrentTimestamp(),
MinerPayouts: []types.SiacoinOutput{{Value: types.CalculateCoinbase(pb.Height)}},
Transactions: []types.Transaction{{
SiacoinInputs: []types.SiacoinInput{{}}, // Will trigger an error on full verification but not partial verification.
}},
}
parent, err := cst.cs.dbGetBlockMap(pb.Block.ParentID)
if err != nil {
t.Fatal(err)
}
badBlock, _ = cst.miner.SolveBlock(badBlock, parent.ChildTarget)
err = cst.cs.AcceptBlock(badBlock)
if err != modules.ErrNonExtendingBlock {
t.Fatal(err)
}
// Build another bock on top of the bad block that is fully valid, this
// will cause a fork and full validation of the bad block, both the bad
// block and this block should be thrown away.
block := types.Block{
ParentID: badBlock.ID(),
Timestamp: types.CurrentTimestamp(),
MinerPayouts: []types.SiacoinOutput{{Value: types.CalculateCoinbase(pb.Height + 1)}},
}
block, _ = cst.miner.SolveBlock(block, parent.ChildTarget) // okay because the target will not change
err = cst.cs.AcceptBlock(block)
if err == nil {
t.Fatal("a bad block failed to cause an error")
}
}
示例5: TestCheckMinerPayouts
// TestCheckMinerPayouts probes the checkMinerPayouts function.
func TestCheckMinerPayouts(t *testing.T) {
// All tests are done at height = 0.
coinbase := types.CalculateCoinbase(0)
// Create a block with a single valid payout.
b := types.Block{
MinerPayouts: []types.SiacoinOutput{
{Value: coinbase},
},
}
if !checkMinerPayouts(b, 0) {
t.Error("payouts evaluated incorrectly when there is only one payout.")
}
// Try a block with an incorrect payout.
b = types.Block{
MinerPayouts: []types.SiacoinOutput{
{Value: coinbase.Sub(types.NewCurrency64(1))},
},
}
if checkMinerPayouts(b, 0) {
t.Error("payouts evaluated incorrectly when there is a too-small payout")
}
// Try a block with 2 payouts.
b = types.Block{
MinerPayouts: []types.SiacoinOutput{
{Value: coinbase.Sub(types.NewCurrency64(1))},
{Value: types.NewCurrency64(1)},
},
}
if !checkMinerPayouts(b, 0) {
t.Error("payouts evaluated incorrectly when there are 2 payouts")
}
// Try a block with 2 payouts that are too large.
b = types.Block{
MinerPayouts: []types.SiacoinOutput{
{Value: coinbase},
{Value: coinbase},
},
}
if checkMinerPayouts(b, 0) {
t.Error("payouts evaluated incorrectly when there are two large payouts")
}
// Create a block with an empty payout.
b = types.Block{
MinerPayouts: []types.SiacoinOutput{
{Value: coinbase},
{},
},
}
if checkMinerPayouts(b, 0) {
t.Error("payouts evaluated incorrectly when there is only one payout.")
}
}
示例6: testFundTransaction
// testFundTransaction funds and completes a transaction using the
// build-your-own transaction functions, checking that a no-refund transaction
// is created that is valid.
func (wt *walletTester) testFundTransaction() error {
// Build a transaction that intentionally needs a refund.
id, err := wt.wallet.RegisterTransaction(types.Transaction{})
fund := wt.wallet.Balance(false).Sub(types.NewCurrency64(1))
if err != nil {
return err
}
_, err = wt.wallet.FundTransaction(id, fund)
if err != nil {
return err
}
wt.tpUpdateWait()
_, _, err = wt.wallet.AddMinerFee(id, fund)
if err != nil {
return err
}
t, err := wt.wallet.SignTransaction(id, true)
if err != nil {
return err
}
err = wt.tpool.AcceptTransaction(t)
if err != nil {
return err
}
wt.tpUpdateWait()
// Check that the length of the created transaction is 1 siacoin, and that
// the unconfirmed balance of the wallet is 1.
if len(t.SiacoinOutputs) != 0 {
return errors.New("expecting 0 siacoin outputs, got non-zero result")
}
if wt.wallet.Balance(true).Cmp(types.NewCurrency64(1)) != 0 {
return errors.New("incorrect balance being reported")
}
// Dump the transaction pool into a block and see that the balance still
// registers correctly.
b, _ := wt.miner.FindBlock()
err = wt.cs.AcceptBlock(b)
if err != nil {
return err
}
wt.csUpdateWait()
// Check that the length of the created transaction is 1 siacoin, and that
// the unconfirmed balance of the wallet is 1 + BlockReward.
if len(t.SiacoinOutputs) != 0 {
return errors.New("wrong number of siacoin outputs - expecting 0")
}
expectedBalance := types.CalculateCoinbase(2).Add(types.NewCurrency64(1))
if bal := wt.wallet.Balance(true); bal.Cmp(expectedBalance) != 0 {
return errors.New("did not arrive at the expected balance")
}
return nil
}
示例7: createConsensusDB
// createConsensusObjects initialzes the consensus portions of the database.
func (cs *ConsensusSet) createConsensusDB(tx *bolt.Tx) error {
// Enumerate and create the database buckets.
buckets := [][]byte{
BlockHeight,
BlockMap,
BlockPath,
Consistency,
SiacoinOutputs,
FileContracts,
SiafundOutputs,
SiafundPool,
}
for _, bucket := range buckets {
_, err := tx.CreateBucket(bucket)
if err != nil {
return err
}
}
// Set the block height to -1, so the genesis block is at height 0.
blockHeight := tx.Bucket(BlockHeight)
underflow := types.BlockHeight(0)
err := blockHeight.Put(BlockHeight, encoding.Marshal(underflow-1))
if err != nil {
return err
}
// Set the siafund pool to 0.
setSiafundPool(tx, types.NewCurrency64(0))
// Update the siafund output diffs map for the genesis block on disk. This
// needs to happen between the database being opened/initilized and the
// consensus set hash being calculated
for _, sfod := range cs.blockRoot.SiafundOutputDiffs {
commitSiafundOutputDiff(tx, sfod, modules.DiffApply)
}
// Add the miner payout from the genesis block to the delayed siacoin
// outputs - unspendable, as the unlock hash is blank.
createDSCOBucket(tx, types.MaturityDelay)
addDSCO(tx, types.MaturityDelay, cs.blockRoot.Block.MinerPayoutID(0), types.SiacoinOutput{
Value: types.CalculateCoinbase(0),
UnlockHash: types.UnlockHash{},
})
// Add the genesis block to the block strucutres - checksum must be taken
// after pushing the genesis block into the path.
pushPath(tx, cs.blockRoot.Block.ID())
if build.DEBUG {
cs.blockRoot.ConsensusChecksum = consensusChecksum(tx)
}
addBlockMap(tx, &cs.blockRoot)
return nil
}
示例8: TestBuriedBadTransaction
// TestBuriedBadTransaction tries submitting a block with a bad transaction
// that is buried under good transactions.
func TestBuriedBadTransaction(t *testing.T) {
if testing.Short() {
t.SkipNow()
}
t.Parallel()
cst, err := createConsensusSetTester("TestBuriedBadTransaction")
if err != nil {
t.Fatal(err)
}
defer cst.Close()
pb := cst.cs.dbCurrentProcessedBlock()
// Create a good transaction using the wallet.
txnValue := types.NewCurrency64(1200)
txnBuilder := cst.wallet.StartTransaction()
err = txnBuilder.FundSiacoins(txnValue)
if err != nil {
t.Fatal(err)
}
txnBuilder.AddSiacoinOutput(types.SiacoinOutput{Value: txnValue})
txnSet, err := txnBuilder.Sign(true)
if err != nil {
t.Fatal(err)
}
err = cst.tpool.AcceptTransactionSet(txnSet)
if err != nil {
t.Fatal(err)
}
// Create a bad transaction
badTxn := types.Transaction{
SiacoinInputs: []types.SiacoinInput{{}},
}
txns := append(cst.tpool.TransactionList(), badTxn)
// Create a block with a buried bad transaction.
block := types.Block{
ParentID: pb.Block.ID(),
Timestamp: types.CurrentTimestamp(),
MinerPayouts: []types.SiacoinOutput{{Value: types.CalculateCoinbase(pb.Height + 1)}},
Transactions: txns,
}
block, _ = cst.miner.SolveBlock(block, pb.ChildTarget)
err = cst.cs.AcceptBlock(block)
if err == nil {
t.Error("buried transaction didn't cause an error")
}
}
示例9: initSetDB
// initDatabase is run when the database. This has become the true
// init function for consensus set
func (cs *ConsensusSet) initSetDB() error {
err := cs.db.startConsistencyGuard()
if err != nil {
return err
}
// add genesis block
err = cs.db.addBlockMap(&cs.blockRoot)
if err != nil {
return err
}
err = cs.db.pushPath(cs.blockRoot.Block.ID())
if err != nil {
return err
}
// Set the siafund pool to 0.
err = cs.db.Update(func(tx *bolt.Tx) error {
sfpBucket := tx.Bucket(SiafundPool)
return sfpBucket.Put(SiafundPool, encoding.Marshal(types.NewCurrency64(0)))
})
if err != nil {
return err
}
// Update the siafundoutput diffs map for the genesis block on
// disk. This needs to happen between the database being
// opened/initilized and the consensus set hash being calculated
for _, sfod := range cs.blockRoot.SiafundOutputDiffs {
cs.commitSiafundOutputDiff(sfod, modules.DiffApply)
}
// Prevent the miner payout for the genesis block from being spent
cs.db.addSiacoinOutputs(cs.blockRoot.Block.MinerPayoutID(0), types.SiacoinOutput{
Value: types.CalculateCoinbase(0),
UnlockHash: types.UnlockHash{},
})
if build.DEBUG {
cs.blockRoot.ConsensusSetHash = cs.consensusSetHash()
cs.db.updateBlockMap(&cs.blockRoot)
}
cs.db.stopConsistencyGuard()
return nil
}
示例10: blockForWork
// Creates a block ready for nonce grinding, also returning the MerkleRoot of
// the block. Getting the MerkleRoot of a block requires encoding and hashing
// in a specific way, which are implementation details we didn't want to
// require external miners to need to worry about. All blocks returned are
// unique, which means all miners can safely start at the '0' nonce.
func (m *Miner) blockForWork() (types.Block, types.Target) {
// Determine the timestamp.
blockTimestamp := types.CurrentTimestamp()
if blockTimestamp < m.earliestTimestamp {
blockTimestamp = m.earliestTimestamp
}
// Create the miner payouts.
subsidy := types.CalculateCoinbase(m.height)
for _, txn := range m.transactions {
for _, fee := range txn.MinerFees {
subsidy = subsidy.Add(fee)
}
}
blockPayouts := []types.SiacoinOutput{types.SiacoinOutput{Value: subsidy, UnlockHash: m.address}}
// Create the list of transacitons, including the randomized transaction.
// The transactions are assembled by calling append(singleElem,
// existingSlic) because doing it the reverse way has some side effects,
// creating a race condition and ultimately changing the block hash for
// other parts of the program. This is related to the fact that slices are
// pointers, and not immutable objects. Use of the builtin `copy` function
// when passing objects like blocks around may fix this problem.
randBytes := make([]byte, types.SpecifierLen)
rand.Read(randBytes)
randTxn := types.Transaction{
ArbitraryData: [][]byte{append(modules.PrefixNonSia[:], randBytes...)},
}
blockTransactions := append([]types.Transaction{randTxn}, m.transactions...)
// Assemble the block
b := types.Block{
ParentID: m.parent,
Timestamp: blockTimestamp,
MinerPayouts: blockPayouts,
Transactions: blockTransactions,
}
return b, m.target
}
示例11: checkCurrency
// checkCurrency verifies that the amount of currency in the system matches the
// amount of currency that is supposed to be in the system.
func (cst *consensusSetTester) checkCurrency() error {
lockID := cst.cs.mu.RLock()
defer cst.cs.mu.RUnlock(lockID)
// Check that there are 10k siafunds.
totalSiafunds := types.NewCurrency64(0)
for _, sfo := range cst.cs.siafundOutputs {
totalSiafunds = totalSiafunds.Add(sfo.Value)
}
if totalSiafunds.Cmp(types.NewCurrency64(types.SiafundCount)) != 0 {
return errors.New("incorrect number of siafunds in the consensus set")
}
// Check that there are the expected number of siacoins.
expectedSiacoins := types.NewCurrency64(0)
for i := types.BlockHeight(0); i <= cst.cs.height(); i++ {
expectedSiacoins = expectedSiacoins.Add(types.CalculateCoinbase(i))
}
totalSiacoins := cst.cs.siafundPool
for _, sco := range cst.cs.siacoinOutputs {
totalSiacoins = totalSiacoins.Add(sco.Value)
}
for _, fc := range cst.cs.fileContracts {
totalSiacoins = totalSiacoins.Add(fc.Payout)
}
for height, dsoMap := range cst.cs.delayedSiacoinOutputs {
if height+types.MaturityDelay > cst.cs.Height() {
for _, dso := range dsoMap {
totalSiacoins = totalSiacoins.Add(dso.Value)
}
}
}
if expectedSiacoins.Cmp(totalSiacoins) != 0 {
return errors.New("incorrect number of siacoins in the consensus set")
}
return nil
}
示例12: dbAddGenesisBlock
// Special handling for the genesis block. No other functions are called on it.
func dbAddGenesisBlock(tx *bolt.Tx) {
id := types.GenesisID
dbAddBlockID(tx, id, 0)
txid := types.GenesisBlock.Transactions[0].ID()
dbAddTransactionID(tx, txid, 0)
for i, sfo := range types.GenesisSiafundAllocation {
sfoid := types.GenesisBlock.Transactions[0].SiafundOutputID(uint64(i))
dbAddSiafundOutputID(tx, sfoid, txid)
dbAddUnlockHash(tx, sfo.UnlockHash, txid)
dbAddSiafundOutput(tx, sfoid, sfo)
}
dbAddBlockFacts(tx, blockFacts{
BlockFacts: modules.BlockFacts{
BlockID: id,
Height: 0,
Difficulty: types.RootTarget.Difficulty(),
Target: types.RootTarget,
TotalCoins: types.CalculateCoinbase(0),
TransactionCount: 1,
SiafundOutputCount: uint64(len(types.GenesisSiafundAllocation)),
},
Timestamp: types.GenesisBlock.Timestamp,
})
}
示例13: checkSiacoinCount
// checkSiacoinCount checks that the number of siacoins countable within the
// consensus set equal the expected number of siacoins for the block height.
func checkSiacoinCount(tx *bolt.Tx) {
// Iterate through all the buckets looking for the delayed siacoin output
// buckets, and check that they are for the correct heights.
var dscoSiacoins types.Currency
err := tx.ForEach(func(name []byte, b *bolt.Bucket) error {
// Check if the bucket is a delayed siacoin output bucket.
if !bytes.HasPrefix(name, prefixDSCO) {
return nil
}
// Sum up the delayed outputs in this bucket.
err := b.ForEach(func(_, delayedOutput []byte) error {
var sco types.SiacoinOutput
err := encoding.Unmarshal(delayedOutput, &sco)
if err != nil {
manageErr(tx, err)
}
dscoSiacoins = dscoSiacoins.Add(sco.Value)
return nil
})
if err != nil {
return err
}
return nil
})
if err != nil {
manageErr(tx, err)
}
// Add all of the siacoin outputs.
var scoSiacoins types.Currency
err = tx.Bucket(SiacoinOutputs).ForEach(func(_, scoBytes []byte) error {
var sco types.SiacoinOutput
err := encoding.Unmarshal(scoBytes, &sco)
if err != nil {
manageErr(tx, err)
}
scoSiacoins = scoSiacoins.Add(sco.Value)
return nil
})
if err != nil {
manageErr(tx, err)
}
// Add all of the payouts from file contracts.
var fcSiacoins types.Currency
err = tx.Bucket(FileContracts).ForEach(func(_, fcBytes []byte) error {
var fc types.FileContract
err := encoding.Unmarshal(fcBytes, &fc)
if err != nil {
manageErr(tx, err)
}
var fcCoins types.Currency
for _, output := range fc.ValidProofOutputs {
fcCoins = fcCoins.Add(output.Value)
}
fcSiacoins = fcSiacoins.Add(fcCoins)
return nil
})
if err != nil {
manageErr(tx, err)
}
// Add all of the siafund claims.
var claimSiacoins types.Currency
err = tx.Bucket(SiafundOutputs).ForEach(func(_, sfoBytes []byte) error {
var sfo types.SiafundOutput
err := encoding.Unmarshal(sfoBytes, &sfo)
if err != nil {
manageErr(tx, err)
}
coinsPerFund := getSiafundPool(tx).Sub(sfo.ClaimStart)
claimCoins := coinsPerFund.Mul(sfo.Value).Div(types.SiafundCount)
claimSiacoins = claimSiacoins.Add(claimCoins)
return nil
})
if err != nil {
manageErr(tx, err)
}
// Count how many coins should exist
deflationBlocks := types.BlockHeight(types.InitialCoinbase - types.MinimumCoinbase)
expectedSiacoins := types.CalculateCoinbase(0).Add(types.CalculateCoinbase(blockHeight(tx))).Div(types.NewCurrency64(2))
if blockHeight(tx) < deflationBlocks {
expectedSiacoins = expectedSiacoins.Mul(types.NewCurrency64(uint64(blockHeight(tx) + 1)))
} else {
expectedSiacoins = expectedSiacoins.Mul(types.NewCurrency64(uint64(deflationBlocks + 1)))
trailingSiacoins := types.NewCurrency64(uint64(blockHeight(tx) - deflationBlocks)).Mul(types.CalculateCoinbase(blockHeight(tx)))
expectedSiacoins = expectedSiacoins.Add(trailingSiacoins)
}
totalSiacoins := dscoSiacoins.Add(scoSiacoins).Add(fcSiacoins).Add(claimSiacoins)
if totalSiacoins.Cmp(expectedSiacoins) != 0 {
diagnostics := fmt.Sprintf("Wrong number of siacoins\nDsco: %v\nSco: %v\nFc: %v\nClaim: %v\n", dscoSiacoins, scoSiacoins, fcSiacoins, claimSiacoins)
if totalSiacoins.Cmp(expectedSiacoins) < 0 {
diagnostics += fmt.Sprintf("total: %v\nexpected: %v\n expected is bigger: %v", totalSiacoins, expectedSiacoins, expectedSiacoins.Sub(totalSiacoins))
} else {
//.........這裏部分代碼省略.........
示例14: testBlockConflicts
// testBlockConflicts adds a transaction to the unconfirmed set, and then adds
// a conflicting transaction to the confirmed set, checking that the conflict
// is properly handled by the pool.
func (tpt *tpoolTester) testBlockConflicts() {
// Put two transactions, a parent and a dependent, into the transaction
// pool. Then create a transaction that is in conflict with the parent.
parent := tpt.emptyUnlockTransaction()
dependent := types.Transaction{
SiacoinInputs: []types.SiacoinInput{
types.SiacoinInput{
ParentID: parent.SiacoinOutputID(0),
},
},
MinerFees: []types.Currency{
parent.SiacoinOutputs[0].Value,
},
}
err := tpt.tpool.AcceptTransaction(parent)
if err != nil {
tpt.t.Fatal(err)
}
tpt.tpUpdateWait()
err = tpt.tpool.AcceptTransaction(dependent)
if err != nil {
tpt.t.Fatal(err)
}
tpt.tpUpdateWait()
// Create a transaction that is in conflict with the parent.
parentValue := parent.SiacoinOutputSum()
conflict := types.Transaction{
SiacoinInputs: parent.SiacoinInputs,
MinerFees: []types.Currency{
parentValue,
},
}
// Mine a block to put the conflict into the confirmed set. 'parent' has
// dependencies of it's own, and 'conflict' has the same dependencies as
// 'parent'. So the block we mine needs to include all of the dependencies
// without including 'parent' or 'dependent'.
tset := tpt.tpool.TransactionSet()
tset = tset[:len(tset)-2] // strip 'parent' and 'dependent'
tset = append(tset, conflict) // add 'conflict'
target, exists := tpt.cs.ChildTarget(tpt.cs.CurrentBlock().ID())
if !exists {
tpt.t.Fatal("unable to recover child target")
}
block := types.Block{
ParentID: tpt.cs.CurrentBlock().ID(),
Timestamp: types.Timestamp(time.Now().Unix()),
MinerPayouts: []types.SiacoinOutput{
types.SiacoinOutput{Value: parentValue.Add(types.CalculateCoinbase(tpt.cs.Height() + 1))},
},
Transactions: tset,
}
for {
block, found := tpt.miner.SolveBlock(block, target)
if found {
err = tpt.cs.AcceptBlock(block)
if err != nil {
tpt.t.Fatal(err)
}
break
}
}
tpt.csUpdateWait()
// Check that 'parent' and 'dependent' have been removed from the
// transaction set, since conflict has made the confirmed set.
if len(tpt.tpool.TransactionSet()) != 0 {
tpt.t.Error("parent and dependent transaction are still in the pool after a conflict has been introduced, have", len(tset))
}
}
示例15: testRewinding
// testRewinding adds transactions in a block, then removes the block and
// verifies that the transaction pool adds the block transactions.
func (tpt *tpoolTester) testRewinding() {
// Put some transactions into the unconfirmed set.
tpt.addSiacoinTransactionToPool()
if len(tpt.tpool.TransactionSet()) == 0 {
tpt.t.Fatal("transaction pool has no transactions")
}
// Prepare an empty block to cause a rewind (by forking).
target, exists := tpt.cs.ChildTarget(tpt.cs.CurrentBlock().ID())
if !exists {
tpt.t.Fatal("unable to recover child target")
}
forkStart := types.Block{
ParentID: tpt.cs.CurrentBlock().ID(),
Timestamp: types.Timestamp(time.Now().Unix()),
MinerPayouts: []types.SiacoinOutput{
types.SiacoinOutput{Value: types.CalculateCoinbase(tpt.cs.Height() + 1)},
},
}
for {
var found bool
forkStart, found = tpt.miner.SolveBlock(forkStart, target)
if found {
break
}
}
// Mine a block with the transaction.
b, _ := tpt.miner.FindBlock()
err := tpt.cs.AcceptBlock(b)
if err != nil {
tpt.t.Fatal(err)
}
tpt.csUpdateWait()
if len(tpt.tpool.TransactionSet()) != 0 {
tpt.t.Fatal("tset should be empty after FindBlock()")
}
// Fork around the block with the transaction.
err = tpt.cs.AcceptBlock(forkStart)
if err != nil && err != modules.ErrNonExtendingBlock {
tpt.t.Fatal(err)
}
target, exists = tpt.cs.ChildTarget(tpt.cs.CurrentBlock().ID())
if !exists {
tpt.t.Fatal("unable to recover child target")
}
forkCommit := types.Block{
ParentID: forkStart.ID(),
Timestamp: types.Timestamp(time.Now().Unix()),
MinerPayouts: []types.SiacoinOutput{
types.SiacoinOutput{Value: types.CalculateCoinbase(tpt.cs.Height() + 1)},
},
}
for {
var found bool
forkCommit, found = tpt.miner.SolveBlock(forkCommit, target)
if found {
tpt.cs.AcceptBlock(forkCommit)
break
}
}
tpt.csUpdateWait()
// Check that the transaction which was once confirmed but no longer is
// confirmed is now unconfirmed.
if len(tpt.tpool.TransactionSet()) == 0 {
tpt.t.Error("tset should contain transactions that used to be confirmed but no longer are")
}
}