diff --git a/InitializationOfNetwork.go b/InitializationOfNetwork.go index faa969c..e5aeb08 100644 --- a/InitializationOfNetwork.go +++ b/InitializationOfNetwork.go @@ -3,35 +3,35 @@ package OracleMiner import ( "encoding/hex" "fmt" - "github.com/FactomProject/FactomCode/common" "github.com/FactomProject/factom" "github.com/pegnet/OracleRecord" "time" + "encoding/json" + "github.com/FactomProject/btcutil/base58" + "sync" ) +var NetworkMutex sync.Mutex + func InitNetwork(mstate *MinerState, minerNumber int, opr *oprecord.OraclePriceRecord) { + NetworkMutex.Lock() + defer NetworkMutex.Unlock() + PegNetChain := mstate.GetProtocolChain() - BPegNetChainID, err := hex.DecodeString(PegNetChain) - if err != nil { - panic("Could not decode the protocol chain:" + err.Error()) - } - opr.SetChainID(BPegNetChainID) + opr.SetChainID(PegNetChain) Coinbase := mstate.GetCoinbasePNTAddress() opr.SetCoinbasePNTAddress(Coinbase) - - bOprChainID, err := hex.DecodeString(mstate.GetProtocolChain()) - if err != nil { + + bOprChainID := base58.Decode(mstate.GetProtocolChain()) + if len(bOprChainID)==0 { panic("No OPR Chain found in config file") } did := mstate.GetIdentityChainID() - BFactomDigitalID, _ := hex.DecodeString(did) - - opr.SetFactomDigitalID(BFactomDigitalID) - opr.SetVersionEntryHash(common.Sha([]byte("an entry")).Bytes()) + opr.SetFactomDigitalID(did) sECAdr := mstate.GetECAddress() ecAdr, err := factom.FetchECAddress(sECAdr) @@ -43,48 +43,30 @@ func InitNetwork(mstate *MinerState, minerNumber int, opr *oprecord.OraclePriceR opr.EC = ecAdr FundWallet(mstate) - + created := false // First check if the network has been initialized. If it hasn't, then create all // the initial structures. This is only needed while testing. - chainid := mstate.GetProtocolChain() + chainid := hex.EncodeToString(base58.Decode(mstate.GetProtocolChain())) if !factom.ChainExists(chainid) { + created = true CreatePegNetChain(mstate) } chainid = mstate.GetOraclePriceRecordChain() if !factom.ChainExists(chainid) { + created = true CreateOPRChain(mstate) } - var entries []*factom.Entry - // Check that we have an asset entry - for { - entries, err = factom.GetAllChainEntries(chainid) - if err == nil { - break - } - time.Sleep(500 * time.Millisecond) - } - // I'm doing a cheap lambda function here because we are looking for a finish, and breaking - // if we find it. - func() { - for _, entry := range entries { - // We are looking for the first Asset Entry. If we upgrade the network - // we will have to search for the 2nd or 3rd, or whatever. Upgrades will - // be determined by the wallet code and the miners. - if len(entry.ExtIDs) > 0 && string(entry.ExtIDs[0]) == "Asset Entry" { - // If we have the Asset Entry, set that hash - opr.SetVersionEntryHash(entry.Hash()) - return - } - } - AddAssetEntry(mstate) - }() - // Check for and create the Oracle Price Records Chain chainid = hex.EncodeToString(bOprChainID) if !factom.ChainExists(chainid) { + created = true CreateOPRChain(mstate) } + + if created { + time.Sleep(time.Duration(mstate.Monitor.directoryblockinseconds)*time.Second) + } return } @@ -268,16 +250,16 @@ func CreateOPRChain(mstate *MinerState) { // The Pegged Network has a defining chain. This function builds and returns the expected defining chain // for the network. -func AddOpr(mstate *MinerState, nonce []byte) { +func AddOpr(mstate *MinerState) { opr := mstate.OPR // Create the OPR Entry // Create the first entry for the OPR Chain oprChainID := mstate.GetOraclePriceRecordChain() - bOpr, err := opr.MarshalBinary() + bOpr, err := json.Marshal(opr) check(err) - entryExtIDs := [][]byte{opr.Nonce[:]} + entryExtIDs := [][]byte{[]byte(opr.Nonce)} assetEntry := NewEntry(oprChainID, entryExtIDs, bOpr) _, err = factom.CommitEntry(assetEntry, opr.EC) diff --git a/config.go b/config.go index 48269ba..6440d6f 100644 --- a/config.go +++ b/config.go @@ -8,6 +8,7 @@ import ( "github.com/zpatrick/go-config" "os/user" "strings" + "github.com/FactomProject/btcutil/base58" ) const protocolname = "pegnet" @@ -51,7 +52,7 @@ func (m *MinerState) GetECAddress() string { func (m *MinerState) GetCoinbasePNTAddress() string { if str, err := m.Config.String("Miner.CoinbasePNTAddress"); err != nil { - panic("No Coinbase PNT Address in Config" + err.Error()) + panic(fmt.Sprintf("Miner %d No Coinbase PNT Address in Config %v",m.MinerNumber,err.Error() )) } else { return str } @@ -80,7 +81,7 @@ func (m *MinerState) GetProtocolChainExtIDs() []string { // in this chain. func (m *MinerState) GetProtocolChain() string { chainid := factom.ComputeChainIDFromStrings(m.GetProtocolChainExtIDs()) - return hex.EncodeToString(chainid) + return base58.Encode(chainid) } func (m *MinerState) GetOraclePriceRecordExtIDs() []string { @@ -105,19 +106,17 @@ func (m *MinerState) GetOraclePriceRecordChain() string { // Returns a pointer to a string for the chainID. Takes the raw chain // if specified, but if not, returns the chainID computed from the fields. // If no chainID is specified in the config file, a nil is returned. -func (m *MinerState) GetIdentityChainID() string { - chainID, err := m.Config.String("Miner.IdentityChain") - if err != nil || len(chainID) == 0 { - fieldscomma, err := m.Config.String("Miner.IdentityChainFields") - fields := strings.Split(fieldscomma, ",") - if err != nil || len(fields) == 0 { - panic("Could not find the Identity Chain ID or Identity Chain Fields for the miner") - } - if len(fields) == 1 && string(fields[0]) == "prototype" { - fields = append(fields, fmt.Sprintf("miner%03d", m.MinerNumber)) - } - bchainID := factom.ComputeChainIDFromStrings(fields) - return hex.EncodeToString(bchainID) +func (m *MinerState) GetIdentityChainID() []string { + chainID58, err := m.Config.String("Miner.IdentityChain") + if err != nil || len(chainID58) == 0 { + + panic("Config file has no Miner.IdentityChain specified") + } - return chainID + fields := strings.Split(chainID58, ",") + if len(fields) == 1 && string(fields[0]) == "prototype" { + fields = append(fields, fmt.Sprintf("miner%03d", m.MinerNumber)) + } + + return fields } diff --git a/defaultconfig.ini b/defaultconfig.ini index 485d9f2..6c9f886 100644 --- a/defaultconfig.ini +++ b/defaultconfig.ini @@ -25,13 +25,13 @@ # and be happy. [Miner] - Network=LOCAL - NumberOfMiners=60 + Network=LOCAL + NumberOfMiners=20 Protocol=PegNet Network=TestNet ECAddress=EC3TsJHUs8bzbbVnratBafub6toRYdgzgbR7kWwCW4tqbmyySRmg FCTAddress=FA2jK2HcLnRdS94dEcU27rF3meoJfpUcZPSinpb7AwQvPRY6RL1Q CoinbasePNTAddress=tPNT2VSeR9ga586m3q85JWruniRjnpjknLtyaj1eJ4X4gnEzbe76b103 - IdentityChainFields=prototype + IdentityChain=prototype [Oracle] APILayerKey=b405fb7e87bfb1d7272641b81a1a58b8 diff --git a/grade.go b/grade.go index 7d74fe5..dc6f482 100644 --- a/grade.go +++ b/grade.go @@ -4,6 +4,8 @@ import ( "fmt" "github.com/FactomProject/factom" "github.com/pegnet/OracleRecord" + "encoding/json" + "github.com/FactomProject/btcutil/base58" ) func GradeLastBlock(mstate *MinerState, opr *oprecord.OraclePriceRecord, dbht int64, miner *Mine) { @@ -24,6 +26,19 @@ func GradeLastBlock(mstate *MinerState, opr *oprecord.OraclePriceRecord, dbht in fmt.Printf("%s\n", ebMR) } + // todo: Make this code a bit more robust + // What we really want to do here is search backwards for the last valid block. We could use + // some intelligence when some block heights didn't give us any valid data. + + // The first block where we build the chains for the PegNet can't be used to mine. + if eb.Header.BlockSequenceNumber == 0 { + if mstate.MinerNumber==1 { + fmt.Println("No previous mining data found") + } + return + } + + for i, ebentry := range eb.EntryList { entry, err := factom.GetEntry(ebentry.EntryHash) if err != nil { @@ -35,7 +50,7 @@ func GradeLastBlock(mstate *MinerState, opr *oprecord.OraclePriceRecord, dbht in continue } newOpr := new(oprecord.OraclePriceRecord) - err = newOpr.UnmarshalBinary(entry.Content) + err = json.Unmarshal(entry.Content,&newOpr) if err != nil { fmt.Println(i, "Error Unmarshalling OPR") continue @@ -44,7 +59,7 @@ func GradeLastBlock(mstate *MinerState, opr *oprecord.OraclePriceRecord, dbht in //continue } newOpr.Entry = entry - copy(newOpr.Nonce[:], entry.ExtIDs[0]) + newOpr.Nonce = string(entry.ExtIDs[0]) if newOpr.ComputeDifficulty() == 0 { fmt.Println(i, "Error Difficulty is zero!") @@ -58,7 +73,9 @@ func GradeLastBlock(mstate *MinerState, opr *oprecord.OraclePriceRecord, dbht in tobepaid, oprlist := oprecord.GradeBlock(oprs) _, _ = tobepaid, oprlist if len(tobepaid) > 0 { - copy(opr.WinningPreviousOPR[:], tobepaid[0].GetEntry(mstate.GetOraclePriceRecordChain()).Hash()) + for i,pay := range tobepaid { + opr.SetWinningPreviousOPR(i+1,base58.Encode(pay.GetEntry(mstate.GetOraclePriceRecordChain()).Hash())) + } //h := tobepaid[0].FactomDigitalID[:6] diff --git a/mine.go b/mine.go index dc31031..7845691 100644 --- a/mine.go +++ b/mine.go @@ -3,16 +3,11 @@ package OracleMiner import ( "github.com/FactomProject/factomd/common/primitives/random" "github.com/pegnet/LXR256" + "github.com/pegnet/OracleRecord" ) type hashFunction func([]byte) []byte -var lx lxr.LXRHash - -func init() { - lx.Init(0x123412341234, 10240000, 256, 5) -} - type Mine struct { MinerNum int // When running many miners, the number of the miner that is this one. started bool // We are mining @@ -40,7 +35,7 @@ func (m *Mine) Init() { // create an LXRHash function for the Lookup XoR hash. m.HashFunction = func(src []byte) []byte { - return lx.Hash(src) + return oprecord.LX.Hash(src) } } diff --git a/util/PeggedNetworkMining/Run.go b/util/PeggedNetworkMining/Run.go index defa68c..12dea1c 100644 --- a/util/PeggedNetworkMining/Run.go +++ b/util/PeggedNetworkMining/Run.go @@ -1,21 +1,21 @@ package main import ( - "encoding/binary" "fmt" "github.com/pegnet/OracleMiner" "math/rand" "time" + "github.com/FactomProject/btcutil/base58" + "encoding/json" ) // GetOPR // To preserve our free access to the APIs we are using, don't actually build the OPR record quicker // than the speedlimit. Faster calls just get the last OPR record func GetOPR(dbht int32, state *OracleMiner.MinerState) []byte { - binary.BigEndian.PutUint64(state.OPR.BlockReward[:], 5000*100000000) state.OPR.GetOPRecord(state.Config) state.OPR.Dbht = dbht - data, err := state.OPR.MarshalBinary() + data, err := json.Marshal(state.OPR) if err != nil { panic("Could not produce an oracle record") } @@ -60,11 +60,12 @@ func RunMiner(minerNumber int) { // sleep for half a block time. miner.Stop() started = false - copy(mstate.OPR.Nonce[:], miner.BestNonce) + mstate.OPR.Nonce = base58.Encode(miner.BestNonce) if mstate.OPR.ComputeDifficulty() > 0 { - OracleMiner.AddOpr(mstate, miner.BestNonce) + OracleMiner.AddOpr(mstate) + fmt.Println("miner ", mstate.MinerNumber, ": Solution") } else { - fmt.Println("miner ", mstate.MinerNumber, ": \"Man, didn't find a solution! Drat!\"") + fmt.Println("miner ", mstate.MinerNumber, ": No Solution") } } case 0: