Compare commits

..

1 Commits

Author SHA1 Message Date
stasatdaglabs
71aca9c360 TEST COMMIT - DO NOT MERGE 2019-10-16 12:06:27 +03:00
12 changed files with 52 additions and 97 deletions

View File

@@ -1,7 +1,7 @@
ISC License
Copyright (c) 2018-2019 DAGLabs
Copyright (c) 2013-2018 The btcsuite developers
Copyright (c) 2013-20 18 The btcsuite developers
Copyright (c) 2015-2016 The Decred developers
Permission to use, copy, modify, and distribute this software for any

View File

@@ -232,8 +232,8 @@ func (node *blockNode) isGenesis() bool {
return len(node.parents) == 0
}
func (node *blockNode) finalityScore(dag *BlockDAG) uint64 {
return node.blueScore / uint64(dag.dagParams.FinalityInterval)
func (node *blockNode) finalityScore() uint64 {
return node.blueScore / FinalityInterval
}
// String returns a string that contains the block hash.

View File

@@ -26,6 +26,9 @@ const (
// maxOrphanBlocks is the maximum number of orphan blocks that can be
// queued.
maxOrphanBlocks = 100
// FinalityInterval is the interval that determines the finality window of the DAG.
FinalityInterval = 100
)
// orphanBlock represents a block that we don't yet have the parent for. It
@@ -733,14 +736,14 @@ func (dag *BlockDAG) updateFinalityPoint() {
}
// We are looking for a new finality point only if the new block's finality score is higher
// by 2 than the existing finality point's
if selectedTip.finalityScore(dag) < dag.lastFinalityPoint.finalityScore(dag)+2 {
if selectedTip.finalityScore() < dag.lastFinalityPoint.finalityScore()+2 {
return
}
var currentNode *blockNode
for currentNode = selectedTip.selectedParent; ; currentNode = currentNode.selectedParent {
// We look for the first node in the selected parent chain that has a higher finality score than the last finality point.
if currentNode.selectedParent.finalityScore(dag) == dag.lastFinalityPoint.finalityScore(dag) {
if currentNode.selectedParent.finalityScore() == dag.lastFinalityPoint.finalityScore() {
break
}
}
@@ -757,7 +760,7 @@ func (dag *BlockDAG) finalizeNodesBelowFinalityPoint(deleteDiffData bool) {
}
var blockHashesToDelete []*daghash.Hash
if deleteDiffData {
blockHashesToDelete = make([]*daghash.Hash, 0, dag.dagParams.FinalityInterval)
blockHashesToDelete = make([]*daghash.Hash, 0, FinalityInterval)
}
for len(queue) > 0 {
var current *blockNode

View File

@@ -1234,22 +1234,22 @@ func testFinalizeNodesBelowFinalityPoint(t *testing.T, deleteDiffData bool) {
flushUTXODiffStore()
return node
}
finalityInterval := dag.dagParams.FinalityInterval
nodes := make([]*blockNode, 0, finalityInterval)
nodes := make([]*blockNode, 0, FinalityInterval)
currentNode := dag.genesis
nodes = append(nodes, currentNode)
for i := 0; i <= finalityInterval*2; i++ {
for i := 0; i <= FinalityInterval*2; i++ {
currentNode = addNode(currentNode)
nodes = append(nodes, currentNode)
}
// Manually set the last finality point
dag.lastFinalityPoint = nodes[finalityInterval-1]
dag.lastFinalityPoint = nodes[FinalityInterval-1]
dag.finalizeNodesBelowFinalityPoint(deleteDiffData)
flushUTXODiffStore()
for _, node := range nodes[:finalityInterval-1] {
for _, node := range nodes[:FinalityInterval-1] {
if !node.isFinalized {
t.Errorf("Node with blue score %d expected to be finalized", node.blueScore)
}
@@ -1267,7 +1267,7 @@ func testFinalizeNodesBelowFinalityPoint(t *testing.T, deleteDiffData bool) {
}
}
for _, node := range nodes[finalityInterval-1:] {
for _, node := range nodes[FinalityInterval-1:] {
if node.isFinalized {
t.Errorf("Node with blue score %d wasn't expected to be finalized", node.blueScore)
}

View File

@@ -20,13 +20,13 @@ import (
// TestFinality checks that the finality mechanism works as expected.
// This is how the flow goes:
// 1) We build a chain of params.FinalityInterval blocks and call its tip altChainTip.
// 2) We build another chain (let's call it mainChain) of 2 * params.FinalityInterval
// 1) We build a chain of blockdag.FinalityInterval blocks and call its tip altChainTip.
// 2) We build another chain (let's call it mainChain) of 2 * blockdag.FinalityInterval
// blocks, which points to genesis, and then we check that the block in that
// chain with height of params.FinalityInterval is marked as finality point (This is
// chain with height of blockdag.FinalityInterval is marked as finality point (This is
// very predictable, because the blue score of each new block in a chain is the
// parents plus one).
// 3) We make a new child to block with height (2 * params.FinalityInterval - 1)
// 3) We make a new child to block with height (2 * blockdag.FinalityInterval - 1)
// in mainChain, and we check that connecting it to the DAG
// doesn't affect the last finality point.
// 4) We make a block that points to genesis, and check that it
@@ -38,7 +38,6 @@ import (
func TestFinality(t *testing.T) {
params := dagconfig.SimNetParams
params.K = 1
params.FinalityInterval = 100
dag, teardownFunc, err := blockdag.DAGSetup("TestFinality", blockdag.Config{
DAGParams: &params,
})
@@ -71,8 +70,8 @@ func TestFinality(t *testing.T) {
genesis := util.NewBlock(params.GenesisBlock)
currentNode := genesis
// First we build a chain of params.FinalityInterval blocks for future use
for i := 0; i < params.FinalityInterval; i++ {
// First we build a chain of blockdag.FinalityInterval blocks for future use
for i := 0; i < blockdag.FinalityInterval; i++ {
currentNode, err = buildNodeToDag([]*daghash.Hash{currentNode.Hash()})
if err != nil {
t.Fatalf("TestFinality: buildNodeToDag unexpectedly returned an error: %v", err)
@@ -81,10 +80,10 @@ func TestFinality(t *testing.T) {
altChainTip := currentNode
// Now we build a new chain of 2 * params.FinalityInterval blocks, pointed to genesis, and
// we expect the block with height 1 * params.FinalityInterval to be the last finality point
// Now we build a new chain of 2 * blockdag.FinalityInterval blocks, pointed to genesis, and
// we expect the block with height 1 * blockdag.FinalityInterval to be the last finality point
currentNode = genesis
for i := 0; i < params.FinalityInterval; i++ {
for i := 0; i < blockdag.FinalityInterval; i++ {
currentNode, err = buildNodeToDag([]*daghash.Hash{currentNode.Hash()})
if err != nil {
t.Fatalf("TestFinality: buildNodeToDag unexpectedly returned an error: %v", err)
@@ -93,7 +92,7 @@ func TestFinality(t *testing.T) {
expectedFinalityPoint := currentNode
for i := 0; i < params.FinalityInterval; i++ {
for i := 0; i < blockdag.FinalityInterval; i++ {
currentNode, err = buildNodeToDag([]*daghash.Hash{currentNode.Hash()})
if err != nil {
t.Fatalf("TestFinality: buildNodeToDag unexpectedly returned an error: %v", err)
@@ -166,9 +165,8 @@ func TestFinality(t *testing.T) {
// a getblocks message it should always be able to send
// all the necessary invs.
func TestFinalityInterval(t *testing.T) {
params := dagconfig.SimNetParams
if params.FinalityInterval > wire.MaxInvPerMsg {
t.Errorf("dagconfig.SimNetParams.FinalityInterval should be lower or equal to wire.MaxInvPerMsg")
if blockdag.FinalityInterval > wire.MaxInvPerMsg {
t.Errorf("blockdag.FinalityInterval should be lower or equal to wire.MaxInvPerMsg")
}
}

View File

@@ -1,7 +1,6 @@
package main
import (
"encoding/hex"
"fmt"
"os"
@@ -29,7 +28,5 @@ func main() {
fmt.Fprintf(os.Stderr, "Failed to generate p2pkh address: %s", err)
os.Exit(1)
}
fmt.Printf("Address: %s\n", addr)
hash160 := addr.Hash160()[:]
fmt.Printf("Hash160 of address (hex): %s\n\n", hex.EncodeToString(hash160))
fmt.Printf("Public key: %s\n\n", addr)
}

View File

@@ -302,7 +302,7 @@ func createTx(walletUTXOSet utxoSet, minAmount uint64, feeRate uint64, targetNum
numOuts = maxNumOuts
}
fee := calcFee(tx, feeRate, numOuts, walletUTXOSet)
fee := calcFee(tx, feeRate, numOuts)
funds -= fee
for i := uint64(0); i < numOuts; i++ {
@@ -350,15 +350,15 @@ func fundTx(walletUTXOSet utxoSet, tx *wire.MsgTx, amount uint64, feeRate uint64
// Add the selected output to the transaction
tx.AddTxIn(wire.NewTxIn(&outpoint, nil))
// Check if transaction has enough funds. If we don't have enough
// Check if transaction has enought funds. If we don't have enough
// coins from he current amount selected to pay the fee, or we have
// less inputs then the targeted amount, continue to grab more coins.
if uint64(len(tx.TxIn)) >= targetNumberOfInputs && isFunded(tx, feeRate, targetNumberOfOutputs, amountSelected, amount, walletUTXOSet) {
if uint64(len(tx.TxIn)) >= targetNumberOfInputs && isFunded(tx, feeRate, targetNumberOfOutputs, amountSelected, amount) {
break
}
}
if !isFunded(tx, feeRate, targetNumberOfOutputs, amountSelected, amount, walletUTXOSet) {
if !isFunded(tx, feeRate, targetNumberOfOutputs, amountSelected, amount) {
return 0, fmt.Errorf("not enough funds for coin selection")
}
@@ -367,40 +367,20 @@ func fundTx(walletUTXOSet utxoSet, tx *wire.MsgTx, amount uint64, feeRate uint64
// Check if the transaction has enough funds to cover the fee
// required for the txn.
func isFunded(tx *wire.MsgTx, feeRate uint64, targetNumberOfOutputs uint64, amountSelected uint64, targetAmount uint64, walletUTXOSet utxoSet) bool {
reqFee := calcFee(tx, feeRate, targetNumberOfOutputs, walletUTXOSet)
func isFunded(tx *wire.MsgTx, feeRate uint64, targetNumberOfOutputs uint64, amountSelected uint64, targetAmount uint64) bool {
reqFee := calcFee(tx, feeRate, targetNumberOfOutputs)
return amountSelected > reqFee && amountSelected-reqFee >= targetAmount
}
func calcFee(msgTx *wire.MsgTx, feeRate uint64, numberOfOutputs uint64, walletUTXOSet utxoSet) uint64 {
txMass := calcTxMass(msgTx, walletUTXOSet)
txMassWithOutputs := txMass + outputsTotalSize(numberOfOutputs)
reqFee := txMassWithOutputs * feeRate
func calcFee(tx *wire.MsgTx, feeRate uint64, numberOfOutputs uint64) uint64 {
txSize := uint64(tx.SerializeSize()) + spendSize*uint64(len(tx.TxIn)) + numberOfOutputs*outputSize + 1
reqFee := uint64(txSize) * feeRate
if reqFee < minTxFee {
return minTxFee
}
return reqFee
}
func outputsTotalSize(numberOfOutputs uint64) uint64 {
return numberOfOutputs*outputSize + uint64(wire.VarIntSerializeSize(numberOfOutputs))
}
func calcTxMass(msgTx *wire.MsgTx, walletUTXOSet utxoSet) uint64 {
previousScriptPubKeys := getPreviousScriptPubKeys(msgTx, walletUTXOSet)
return blockdag.CalcTxMass(util.NewTx(msgTx), previousScriptPubKeys)
}
func getPreviousScriptPubKeys(msgTx *wire.MsgTx, walletUTXOSet utxoSet) [][]byte {
previousScriptPubKeys := make([][]byte, len(msgTx.TxIn))
for i, txIn := range msgTx.TxIn {
outpoint := txIn.PreviousOutpoint
prevOut := walletUTXOSet[outpoint]
previousScriptPubKeys[i] = prevOut.ScriptPubKey
}
return previousScriptPubKeys
}
func applyConfirmedTransactionsAndResendNonAccepted(client *txgenClient, walletTxs map[daghash.TxID]*walletTransaction, walletUTXOSet utxoSet,
blockChainHeight uint64, txChan chan *wire.MsgTx) error {
for txID, walletTx := range walletTxs {

View File

@@ -137,9 +137,6 @@ type Params struct {
// block.
TargetTimePerBlock time.Duration
// FinalityInterval is the interval that determines the finality window of the DAG.
FinalityInterval int
// TimestampDeviationTolerance is the maximum offset a block timestamp
// is allowed to be in the future before it gets delayed
TimestampDeviationTolerance uint64
@@ -208,7 +205,6 @@ var MainNetParams = Params{
BlockCoinbaseMaturity: 100,
SubsidyReductionInterval: 210000,
TargetTimePerBlock: time.Second * 1, // 1 second
FinalityInterval: 1000,
DifficultyAdjustmentWindowSize: difficultyAdjustmentWindowSize,
TimestampDeviationTolerance: timestampDeviationTolerance,
GenerateSupported: false,
@@ -269,7 +265,6 @@ var RegressionNetParams = Params{
BlockCoinbaseMaturity: 100,
SubsidyReductionInterval: 150,
TargetTimePerBlock: time.Second * 1, // 1 second
FinalityInterval: 1000,
DifficultyAdjustmentWindowSize: difficultyAdjustmentWindowSize,
TimestampDeviationTolerance: timestampDeviationTolerance,
GenerateSupported: true,
@@ -328,7 +323,6 @@ var TestNetParams = Params{
BlockCoinbaseMaturity: 100,
SubsidyReductionInterval: 210000,
TargetTimePerBlock: time.Second * 1, // 1 second
FinalityInterval: 1000,
DifficultyAdjustmentWindowSize: difficultyAdjustmentWindowSize,
TimestampDeviationTolerance: timestampDeviationTolerance,
GenerateSupported: true,
@@ -393,7 +387,6 @@ var SimNetParams = Params{
BlockCoinbaseMaturity: 100,
SubsidyReductionInterval: 210000,
TargetTimePerBlock: time.Second * 1, // 1 second
FinalityInterval: 1000,
DifficultyAdjustmentWindowSize: difficultyAdjustmentWindowSize,
TimestampDeviationTolerance: timestampDeviationTolerance,
GenerateSupported: true,
@@ -450,7 +443,6 @@ var DevNetParams = Params{
BlockCoinbaseMaturity: 100,
SubsidyReductionInterval: 210000,
TargetTimePerBlock: time.Second * 1, // 1 second
FinalityInterval: 1000,
DifficultyAdjustmentWindowSize: difficultyAdjustmentWindowSize,
TimestampDeviationTolerance: timestampDeviationTolerance,
GenerateSupported: true,

View File

@@ -71,7 +71,7 @@ const (
// trickleTimeout is the duration of the ticker which trickles down the
// inventory to a peer.
trickleTimeout = 100 * time.Millisecond
trickleTimeout = 10 * time.Second
)
var (

View File

@@ -13,41 +13,27 @@ then
echo ""
echo -e "\t--rm\t\tRemove dockers prior to running them, to clear data"
echo -e "\t--debug\t\tEnable debugging on second server. Server will not start until debugger is attached"
echo -e "\t--no-build\t\tRun without building docker images"
echo -e "\t--only-build\t\tBuild docker images without running"
exit
fi
if [[ $* == *--no-build* ]] && [[ $* == *--only-build* ]]
then
echo "--no-build and --only-build may not be passed together"
exit
fi
export SERVICE_NAME=btcd
export GIT_COMMIT=$(git rev-parse --short=12 HEAD)
if [[ $* != *--no-build* ]]
docker build -t "${SERVICE_NAME}:${GIT_COMMIT}" . \
-f docker/Dockerfile.dev \
|| fatal 'Failed to build the docker image'
docker tag "${SERVICE_NAME}:${GIT_COMMIT}" "${SERVICE_NAME}:latest"
cd docker
if [[ $* == *--rm* ]]
then
docker build -t "${SERVICE_NAME}:${GIT_COMMIT}" . \
-f docker/Dockerfile.dev \
|| fatal 'Failed to build the docker image'
docker tag "${SERVICE_NAME}:${GIT_COMMIT}" "${SERVICE_NAME}:latest"
docker-compose rm -f
fi
if [[ $* != *--only-build* ]]
if [[ $* == *--debug* ]]
then
cd docker
if [[ $* == *--rm* ]]
then
docker-compose rm -f
fi
if [[ $* == *--debug* ]]
then
docker-compose up first second-debug
else
docker-compose up first second
fi
docker-compose up first second-debug
else
docker-compose up first second
fi

View File

@@ -551,7 +551,6 @@ func (s *Server) jsonRPCRead(w http.ResponseWriter, r *http.Request, isAdmin boo
if parsedCmd.err != nil {
jsonErr = parsedCmd.err
} else {
log.Debugf("HTTP server received command <%s> from %s", parsedCmd.method, r.RemoteAddr)
result, jsonErr = s.standardCmdResult(parsedCmd, closeChan)
}
}

View File

@@ -1022,7 +1022,7 @@ out:
c.SendMessage(reply, nil)
continue
}
log.Debugf("Websocket server received command <%s> from %s", cmd.method, c.addr)
log.Debugf("Received command <%s> from %s", cmd.method, c.addr)
// Check auth. The client is immediately disconnected if the
// first request of an unauthentiated websocket client is not