job.go raw

   1  package job
   2  
   3  //
   4  // import (
   5  // 	"errors"
   6  // 	"github.com/p9c/p9/pkg/chaincfg"
   7  // 	"time"
   8  //
   9  // 	"github.com/niubaoshu/gotiny"
  10  //
  11  // 	"github.com/p9c/p9/pkg/blockchain"
  12  // 	"github.com/p9c/p9/pkg/chainhash"
  13  // 	"github.com/p9c/p9/pkg/blockchain/fork"
  14  // 	"github.com/p9c/p9/pkg/wire"
  15  // 	"github.com/p9c/p9/pkg/util"
  16  // )
  17  //
  18  
  19  var Magic = []byte{'j', 'o', 'b', 1}
  20  
  21  //
  22  // type Job struct {
  23  // 	// IPs             map[string]struct{}
  24  // 	// P2PListenerPort uint16
  25  // 	// RPCListenerPort uint16
  26  // 	ControllerNonce uint64
  27  // 	Height          int32
  28  // 	PrevBlockHash   *chainhash.Hash
  29  // 	MinTimestamp    time.Time
  30  // 	Diffs           blockchain.Diffs
  31  // 	Merkles         blockchain.Merkles
  32  // 	// CoinBases       map[int32]*util.Tx
  33  // }
  34  //
  35  // // Get returns a message broadcast by a node and each field is decoded where
  36  // // possible avoiding memory allocation (slicing the data). Yes, this is not
  37  // // concurrent safe, put a mutex in to share it. Using the same principles as
  38  // // used in FlatBuffers, we define a message type that instead of using a reflect
  39  // // based encoder, there is a creation function, and a set of methods that
  40  // // extracts the individual requested field without copying memory, or
  41  // // deserialize their contents which will be concurrent safe The varying coinbase
  42  // // payment values are in transaction 0 last output, the individual varying
  43  // // transactions are stored separately and will be reassembled at the end
  44  // func Get(
  45  // 	node *blockchain.BlockChain,
  46  // 	activeNet *chaincfg.Params,
  47  // 	uuid uint64,
  48  // 	mB *util.Block,
  49  // ) (cbs *map[int32]*util.Tx, out []byte, txr []*util.Tx,) {
  50  // 	_temp := make(map[int32]*util.Tx)
  51  // 	cbs = &_temp
  52  // 	bH := node.BestSnapshot().Height + 1
  53  // 	tip := node.BestChain.Tip()
  54  // 	bitsMap := make(blockchain.Diffs)
  55  // 	var e error
  56  // 	df, ok := tip.Diffs.Load().(blockchain.Diffs)
  57  // 	if df == nil || !ok ||
  58  // 		len(df) != len(fork.List[1].AlgoVers) {
  59  // 		if bitsMap, e = node.CalcNextRequiredDifficultyPlan9Controller(tip); E.Chk(e) {
  60  // 			return
  61  // 		}
  62  // 		tip.Diffs.Store(bitsMap)
  63  // 	} else {
  64  // 		bitsMap = tip.Diffs.Load().(blockchain.Diffs)
  65  // 	}
  66  // 	// Now we need to get the values for coinbase for each algorithm then regenerate
  67  // 	// the merkle roots To mine this block a miner only needs the matching merkle
  68  // 	// roots for the version number but to get them first get the values
  69  // 	var val int64
  70  // 	mTS := make(map[int32]*chainhash.Hash)
  71  // 	mBtx := mB.Transactions()
  72  // 	root := len(mBtx) - 1
  73  // 	coinbase := mBtx[root]
  74  // 	transactions := mB.Transactions()[:root]
  75  // 	txr = make([]*util.Tx, len(transactions))
  76  // 	for i, v := range transactions {
  77  // 		txr[i] = v
  78  // 	}
  79  // 	nbH := bH
  80  // 	if (activeNet.Net == wire.MainNet &&
  81  // 		nbH == fork.List[1].ActivationHeight) ||
  82  // 		(activeNet.Net == wire.TestNet3 &&
  83  // 			nbH == fork.List[1].TestnetStart) {
  84  // 		nbH++
  85  // 	}
  86  //
  87  // 	for i := range bitsMap {
  88  // 		// set value according to version and block height
  89  // 		val = blockchain.CalcBlockSubsidy(nbH, activeNet, i)
  90  // 		txc := coinbase.MsgTx().Copy()
  91  // 		txc.TxOut[len(txc.TxOut)-1].Value = val
  92  // 		txx := util.NewTx(txc.Copy())
  93  // 		// D.S(coinbase)
  94  // 		(*cbs)[i] = txx
  95  // 		// D.Ln("coinbase for version", i, txx.MsgTx().TxOut[len(txx.MsgTx().TxOut)-1].Value)
  96  // 		mTree := blockchain.BuildMerkleTreeStore(
  97  // 			append(txr, txx), false,
  98  // 		)
  99  // 		// D.S(mTree)
 100  // 		mr := mTree.GetRoot()
 101  // 		if mr == nil {
 102  // 			e = errors.New("got a nil merkle root")
 103  // 			panic(e)
 104  // 			return
 105  // 		}
 106  // 		mTS[i] = mr
 107  // 	}
 108  // 	jrb := Job{
 109  // 		ControllerNonce: uuid,
 110  // 		Height:          bH,
 111  // 		PrevBlockHash:   &mB.WireBlock().Header.PrevBlock,
 112  // 		Diffs:           bitsMap,
 113  // 		Merkles:         mTS,
 114  // 		MinTimestamp:    tip.Header().Timestamp.Truncate(time.Second).Add(time.Second),
 115  // 	}
 116  // 	// jrb.CoinBases= make(map[int32]*util.Tx)
 117  // 	// for i := range *cbs {
 118  // 	// 	jrb.CoinBases[i] = (*cbs)[i]
 119  // 	// }
 120  // 	out = gotiny.Marshal(&jrb)
 121  // 	// D.S(jrb)
 122  // 	// D.S(out)
 123  // 	// var testy []byte
 124  // 	// for i := range out {
 125  // 	// 	testy = append(testy, out[i])
 126  // 	// }
 127  // 	// var jr Job
 128  // 	// D.Ln(gotiny.Unmarshal(testy, &jr))
 129  // 	// D.S(jr)
 130  // 	// D.Ln("job size", len(jobber))
 131  // 	// return Container{*msg.CreateContainer(Magic)}, txr
 132  // 	return cbs, out, txr
 133  // }
 134  //
 135  // //
 136  // // // LoadContainer takes a message byte slice payload and loads it into a
 137  // // // container ready to be decoded
 138  // // func LoadContainer(b []byte) (out Container) {
 139  // // 	out.Data = b
 140  // // 	return
 141  // // }
 142  // //
 143  // // func (j *Container) GetIPs() []*net.IP {
 144  // // 	return IPs.New().DecodeOne(j.Get(0)).Get()
 145  // // }
 146  // //
 147  // // func (j *Container) GetP2PListenersPort() uint16 {
 148  // // 	return Uint16.New().DecodeOne(j.Get(1)).Get()
 149  // // }
 150  // //
 151  // // func (j *Container) GetRPCListenersPort() uint16 {
 152  // // 	return Uint16.New().DecodeOne(j.Get(2)).Get()
 153  // // }
 154  // //
 155  // // func (j *Container) GetControllerListenerPort() uint16 {
 156  // // 	return Uint16.New().DecodeOne(j.Get(3)).Get()
 157  // // }
 158  // //
 159  // // func (j *Container) GetNewHeight() (out int32) {
 160  // // 	return Int32.New().DecodeOne(j.Get(4)).Get()
 161  // // }
 162  // //
 163  // // func (j *Container) GetPrevBlockHash() (out *chainhash.Hash) {
 164  // // 	return Hash.New().DecodeOne(j.Get(5)).Get()
 165  // // }
 166  // //
 167  // // func (j *Container) GetBitses() blockchain.Bits {
 168  // // 	return Bits.NewBitses().DecodeOne(j.Get(6)).Get()
 169  // // }
 170  // //
 171  // // // GetHashes returns the merkle roots per version
 172  // // func (j *Container) GetHashes() (out map[int32]*chainhash.Hash) {
 173  // // 	return Merkles.NewHashes().DecodeOne(j.Get(7)).Get()
 174  // // }
 175  // //
 176  // // func (j *Container) String() (s string) {
 177  // // 	s += fmt.Sprint("\ntype '"+string(Magic)+"' elements:", j.Count())
 178  // // 	s += "\n"
 179  // // 	ips := j.GetIPs()
 180  // // 	s += "1 IPs:"
 181  // // 	for i := range ips {
 182  // // 		s += fmt.Sprint(" ", ips[i].String())
 183  // // 	}
 184  // // 	s += "\n"
 185  // // 	s += fmt.Sprint("2 P2PListenersPort: ", j.GetP2PListenersPort())
 186  // // 	s += "\n"
 187  // // 	s += fmt.Sprint("3 RPCListenersPort: ", j.GetRPCListenersPort())
 188  // // 	s += "\n"
 189  // // 	s += fmt.Sprint(
 190  // // 		"4 ControllerListenerPort: ",
 191  // // 		j.GetControllerListenerPort(),
 192  // // 	)
 193  // // 	s += "\n"
 194  // // 	h := j.GetNewHeight()
 195  // // 	s += fmt.Sprint("5 Block height: ", h)
 196  // // 	s += "\n"
 197  // // 	s += fmt.Sprintf(
 198  // // 		"6 Previous Block Hash (sha256d): %064x",
 199  // // 		j.GetPrevBlockHash().CloneBytes(),
 200  // // 	)
 201  // // 	s += "\n"
 202  // // 	bitses := j.GetBitses()
 203  // // 	s += fmt.Sprint("7 Difficulty targets:\n")
 204  // // 	var sortedBitses []int
 205  // // 	for i := range bitses {
 206  // // 		sortedBitses = append(sortedBitses, int(i))
 207  // // 	}
 208  // // 	txsort.Ints(sortedBitses)
 209  // // 	for i := range sortedBitses {
 210  // // 		s += fmt.Sprintf(
 211  // // 			"  %2d %-10v %d %064x",
 212  // // 			sortedBitses[i],
 213  // // 			fork.List[fork.GetCurrent(h)].AlgoVers[int32(sortedBitses[i])],
 214  // // 			bitses[int32(sortedBitses[i])],
 215  // // 			fork.CompactToBig(bitses[int32(sortedBitses[i])]).Bytes(),
 216  // // 		)
 217  // // 		s += "\n"
 218  // // 	}
 219  // // 	s += "8 Merkles:\n"
 220  // // 	hashes := j.GetHashes()
 221  // // 	for i := range sortedBitses {
 222  // // 		s += fmt.Sprintf(
 223  // // 			"  %2d %s\n", sortedBitses[i],
 224  // // 			hashes[int32(sortedBitses[i])].String(),
 225  // // 		)
 226  // // 	}
 227  // //
 228  // // 	// s += spew.Sdump(j.GetHashes())
 229  // // 	return
 230  // // }
 231  // //
 232  // // //
 233  // // // // Struct returns a handy Go struct version This can be used at the start of a
 234  // // // // new block to get a handy struct, the first work received triggers startup and
 235  // // // // locks the worker into sending solutions there, until there is a new
 236  // // // // PrevBlockHash, the work controller (kopach) only responds to updates from
 237  // // // // this first one (or if it stops sending) - the controller keeps track of
 238  // // // // individual controller servers multicasting and when it deletes a newly gone
 239  // // // // dark controller when it comes to send if it isn't found it falls back to the
 240  // // // // next available to submit
 241  // // // func (j *Container) Struct() (out Job) {
 242  // // // 	out = Job{
 243  // // // 		IPs:             j.GetIPs(),
 244  // // // 		P2PListenerPort: j.GetP2PListenersPort(),
 245  // // // 		RPCListenerPort: j.GetRPCListenersPort(),
 246  // // // 		ControllerPort:      j.GetControllerListenerPort(),
 247  // // // 		Height:          j.GetNewHeight(),
 248  // // // 		PrevBlockHash:   j.GetPrevBlockHash(),
 249  // // // 		Bits:          j.GetBitses(),
 250  // // // 		Merkles:          j.GetHashes(),
 251  // // // 	}
 252  // // // 	return
 253  // // // }
 254  //
 255  // // GetMsgBlock takes the handy go struct version and returns a wire.WireBlock
 256  // // ready for giving nonce extranonce and computing the merkel root based on the
 257  // // extranonce in the coinbase as needs to be done when mining, so this would be
 258  // // called for each round for each algorithm to start.
 259  // func (j *Job) GetMsgBlock(version int32) (out *wire.WireBlock) {
 260  // 	found := false
 261  // 	for i := range j.Diffs {
 262  // 		if i == version {
 263  // 			found = true
 264  // 		}
 265  // 	}
 266  // 	if found {
 267  // 		tn := time.Now().Truncate(time.Second)
 268  // 		if tn.Sub(j.MinTimestamp) < time.Second {
 269  // 			tn = j.MinTimestamp
 270  // 		}
 271  // 		out = &wire.WireBlock{
 272  // 			Header: wire.BlockHeader{
 273  // 				Version:    version,
 274  // 				PrevBlock:  *j.PrevBlockHash,
 275  // 				MerkleRoot: *j.Merkles[version],
 276  // 				Timestamp:  tn,
 277  // 			},
 278  // 			// Transactions: j.Txs,
 279  // 		}
 280  // 	}
 281  // 	return
 282  // }
 283