gitlab.com/SiaPrime/SiaPrime@v1.4.1/modules/miningpool/utils.go (about) 1 package pool 2 3 import ( 4 "bytes" 5 "errors" 6 "fmt" 7 "math/big" 8 "runtime" 9 "strconv" 10 11 "gitlab.com/SiaPrime/SiaPrime/types" 12 ) 13 14 func interfaceify(strs []string) []interface{} { 15 newslice := make([]interface{}, len(strs)) 16 for i, v := range strs { 17 newslice[i] = v 18 } 19 return newslice 20 } 21 22 func trace() { 23 pc := make([]uintptr, 10) // at least 1 entry needed 24 runtime.Callers(2, pc) 25 f := runtime.FuncForPC(pc[0]) 26 file, line := f.FileLine(pc[0]) 27 fmt.Printf("%s:%d %s\n", file, line, f.Name()) 28 } 29 30 func sPrintID(id uint64) string { 31 return fmt.Sprintf("%016x", id) 32 } 33 34 func ssPrintID(id int64) string { 35 return fmt.Sprintf("%d", id) 36 } 37 38 func sPrintTx(txn types.Transaction) string { 39 var buffer bytes.Buffer 40 // TODO print unlock conditions 41 for i, input := range txn.SiacoinInputs { 42 buffer.WriteString(fmt.Sprintf("Siacoin Input: %d, Parent ID: %s\n", i, input.ParentID)) 43 } 44 for i, output := range txn.SiacoinOutputs { 45 buffer.WriteString(fmt.Sprintf("Siacoin Output: %d, ID: %s,\n Value: %s, Unlock Hash: %s\n", 46 i, txn.SiacoinOutputID(uint64(i)).String(), output.Value.String(), output.UnlockHash)) 47 } 48 // TODO FileContracts, FileContractRevisions, StorageProofs, SiafundInputs, SiafundOutputs 49 for i, fee := range txn.MinerFees { 50 buffer.WriteString(fmt.Sprintf("Miner Fee: %d, Value: %s\n", i, fee.String())) 51 } 52 for i, datum := range txn.ArbitraryData { 53 buffer.WriteString(fmt.Sprintf("Arbitrary Datum: %d, Value: %s\n", i, datum)) 54 } 55 // TODO rest of transaction 56 return buffer.String() 57 } 58 59 // TODO 60 func sPrintBlock(b types.Block) string { 61 var buffer bytes.Buffer 62 buffer.WriteString(fmt.Sprintf("Block ID: %s\n, Parent ID: %d\nNonce: %d\nTimestamp: %d\n", b.ID(), b.ParentID, b.Nonce, b.Timestamp)) 63 buffer.WriteString("\tMiner Payouts:\n") 64 for i, txn := range b.MinerPayouts { 65 buffer.WriteString(fmt.Sprintf("\t\tPayout %d: %s\n", i, txn)) 66 } 67 buffer.WriteString("\tTransactions:\n") 68 for i, txn := range b.Transactions { 69 buffer.WriteString(fmt.Sprintf("\t\tTx %d:\n", i)) 70 buffer.WriteString(sPrintTx(txn)) 71 buffer.WriteString("\n") 72 } 73 buffer.WriteString("\n") 74 return buffer.String() 75 } 76 77 func printWithSuffix(number types.Currency) string { 78 num := number.Big().Uint64() 79 80 if num > 1000000000000000 { 81 return fmt.Sprintf("%dP", num/1000000000000000) 82 } 83 if num > 1000000000000 { 84 return fmt.Sprintf("%dT", num/1000000000000) 85 } 86 if num > 1000000000 { 87 return fmt.Sprintf("%dG", num/1000000000) 88 } 89 if num > 1000000 { 90 return fmt.Sprintf("%dM", num/1000000) 91 } 92 return fmt.Sprintf("%d", num) 93 } 94 95 // IntToTarget converts a big.Int to a Target. 96 func intToTarget(i *big.Int) (t types.Target, err error) { 97 // Check for negatives. 98 if i.Sign() < 0 { 99 err = errors.New("Negative target") 100 return 101 } 102 // In the event of overflow, return the maximum. 103 if i.BitLen() > 256 { 104 err = errors.New("Target is too high") 105 return 106 } 107 b := i.Bytes() 108 offset := len(t[:]) - len(b) 109 copy(t[offset:], b) 110 return 111 } 112 113 func difficultyToTarget(difficulty float64) (target types.Target, err error) { 114 diffAsBig := big.NewFloat(difficulty) 115 116 diffOneString := "0x00000000ffff0000000000000000000000000000000000000000000000000000" 117 targetOneAsBigInt := &big.Int{} 118 targetOneAsBigInt.SetString(diffOneString, 0) 119 120 targetAsBigFloat := &big.Float{} 121 targetAsBigFloat.SetInt(targetOneAsBigInt) 122 targetAsBigFloat.Quo(targetAsBigFloat, diffAsBig) 123 targetAsBigInt, _ := targetAsBigFloat.Int(nil) 124 target, err = intToTarget(targetAsBigInt) 125 return 126 } 127 128 func caculateRewardRatio(siaSessionDifficulty, blockDifficulty *big.Int) float64 { 129 sessionAsBigFloat := &big.Float{} 130 sessionAsBigFloat.SetInt(siaSessionDifficulty) 131 blockAsBigFloat := &big.Float{} 132 blockAsBigFloat.SetInt(blockDifficulty) 133 resultAsBigFloat := &big.Float{} 134 135 resultAsBigFloat.Quo(sessionAsBigFloat, blockAsBigFloat) 136 result, _ := resultAsBigFloat.Float64() 137 138 if result > 1.0 { 139 return 1.0 140 } 141 return result 142 } 143 144 func currencyToAmount(value types.Currency) float64 { 145 v := value.String()[0 : len(value.String())-16] 146 f, _ := strconv.ParseFloat(v, 64) 147 return f / 1e8 148 } 149 150 // 151 // The following function is covered by the included license 152 // The function was copied from https://github.com/btcsuite/btcd 153 // 154 // ISC License 155 156 // Copyright (c) 2013-2017 The btcsuite developers 157 // Copyright (c) 2015-2016 The Decred developers 158 159 // Permission to use, copy, modify, and distribute this software for any 160 // purpose with or without fee is hereby granted, provided that the above 161 // copyright notice and this permission notice appear in all copies. 162 163 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 164 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 165 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 166 // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 167 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 168 // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 169 // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 170 171 // BigToCompact converts a whole number N to a compact representation using 172 // an unsigned 32-bit number. The compact representation only provides 23 bits 173 // of precision, so values larger than (2^23 - 1) only encode the most 174 // significant digits of the number. See CompactToBig for details. 175 func BigToCompact(n *big.Int) uint32 { 176 // No need to do any work if it's zero. 177 if n.Sign() == 0 { 178 return 0 179 } 180 181 // Since the base for the exponent is 256, the exponent can be treated 182 // as the number of bytes. So, shift the number right or left 183 // accordingly. This is equivalent to: 184 // mantissa = mantissa / 256^(exponent-3) 185 var mantissa uint32 186 exponent := uint(len(n.Bytes())) 187 if exponent <= 3 { 188 mantissa = uint32(n.Bits()[0]) 189 mantissa <<= 8 * (3 - exponent) 190 } else { 191 // Use a copy to avoid modifying the caller's original number. 192 tn := new(big.Int).Set(n) 193 mantissa = uint32(tn.Rsh(tn, 8*(exponent-3)).Bits()[0]) 194 } 195 196 // When the mantissa already has the sign bit set, the number is too 197 // large to fit into the available 23-bits, so divide the number by 256 198 // and increment the exponent accordingly. 199 if mantissa&0x00800000 != 0 { 200 mantissa >>= 8 201 exponent++ 202 } 203 204 // Pack the exponent, sign bit, and mantissa into an unsigned 32-bit 205 // int and return it. 206 compact := uint32(exponent<<24) | mantissa 207 if n.Sign() < 0 { 208 compact |= 0x00800000 209 } 210 return compact 211 }