-
Notifications
You must be signed in to change notification settings - Fork 14
/
estimate.go
135 lines (121 loc) · 3.29 KB
/
estimate.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// tokucore
//
// Copyright 2019 by KeyFuse Labs
// BSD License
package xcore
import (
"github.com/keyfuse/tokucore/xbase"
)
const (
// inputP2PKHSigScriptSize is the worst case (largest) serialize size
// of a transaction input script that redeems a compressed P2PKH output.
// It is calculated as:
//
// - OP_DATA_73
// - 72 bytes DER signature + 1 byte sighash
// - OP_DATA_33
// - 33 bytes serialized compressed pubkey
inputP2PKHSigScriptSize = 1 + 73 + 1 + 33
// inputP2PKHSize is the worst case (largest) serialize size of a
// transaction input redeeming a compressed P2PKH output. It is
// calculated as:
//
// - 32 bytes previous tx
// - 4 bytes output index
// - 1 byte compact int encoding value 107
// - 107 bytes signature script
// - 4 bytes sequence
inputP2PKHSize = 32 + 4 + 1 + inputP2PKHSigScriptSize + 4
// Witness datas.
inputWitnessSignatureSize = 73 // <signature> - 72 bytes DER signature + 1 byte sighash
inputWitnessPubKeySize = 33 // <pubkey> - 33 bytes serialized compressed pubkey
)
// EstimateSize --
// returns a worst case serialize size estimate for a
// signed transaction that spends inputCount number of compressed P2PKH outputs
// and contains each transaction output from txOuts. The estimated size is
// incremented for an additional P2PKH change output if addChangeOutput is true.
func EstimateSize(txins []*TxIn, txouts []*TxOut) int64 {
baseSize := 0
witnessSize := 0
// Core size.
{
// Version.
baseSize += 4
// Input size.
{
txinNums := len(txins)
baseSize += xbase.VarIntSerializeSize(uint64(txinNums))
for _, in := range txins {
if !in.HasWitness() {
baseSize += inputP2PKHSize
}
}
}
// Output size.
{
txoutNums := len(txouts)
baseSize += xbase.VarIntSerializeSize(uint64(txoutNums))
for _, out := range txouts {
baseSize += (8 + len(out.Script))
}
}
// Locktime.
baseSize += 4
}
// Witness Size.
{
var hasWitness bool
for _, in := range txins {
if in.HasWitness() {
hasWitness = true
break
}
}
if hasWitness {
for _, in := range txins {
if in.HasWitness() {
// Witness slice varlen.
witnessSize += xbase.VarIntSerializeSize(uint64(2))
witnessSize += xbase.VarIntSerializeSize(uint64(inputWitnessSignatureSize))
witnessSize += xbase.VarIntSerializeSize(uint64(inputWitnessPubKeySize))
} else {
witnessSize += xbase.VarIntSerializeSize(uint64(0))
}
}
}
}
return int64((baseSize*(witnessScaleFactor-1) + (baseSize + witnessSize)) / witnessScaleFactor)
}
// EstimateNormalSize -- estimate the normal size by input and output count.
func EstimateNormalSize(ins int, outs int) int64 {
baseSize := 0
// Core size.
{
// Version.
baseSize += 4
// Input size.
{
baseSize += xbase.VarIntSerializeSize(uint64(ins))
baseSize += inputP2PKHSize * ins
}
// Output size.
{
baseSize += xbase.VarIntSerializeSize(uint64(outs))
// 8 value size.
// 25 is the p2pkh script length.
baseSize += (8 + 25) * outs
}
// Locktime.
baseSize += 4
}
return int64(baseSize)
}
// EstimateFees -- estimate the fee.
func EstimateFees(estimateSize int64, relayFeePerKb int64) int64 {
fees := 0.0
if relayFeePerKb > 0 {
fees = (float64(relayFeePerKb) / float64(1000)) * float64(estimateSize)
}
return int64(fees)
}