-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PegNet OPR Chain #40
base: develop
Are you sure you want to change the base?
PegNet OPR Chain #40
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -32,12 +32,16 @@ import ( | |||||||||||||
"github.com/Factom-Asset-Tokens/fatd/db/entries" | ||||||||||||||
"github.com/Factom-Asset-Tokens/fatd/db/metadata" | ||||||||||||||
"github.com/Factom-Asset-Tokens/fatd/db/nftokens" | ||||||||||||||
"github.com/Factom-Asset-Tokens/fatd/db/pegnet" | ||||||||||||||
"github.com/Factom-Asset-Tokens/fatd/fat" | ||||||||||||||
"github.com/Factom-Asset-Tokens/fatd/fat/fat0" | ||||||||||||||
"github.com/Factom-Asset-Tokens/fatd/fat/fat1" | ||||||||||||||
"github.com/pegnet/pegnet/modules/grader" | ||||||||||||||
) | ||||||||||||||
|
||||||||||||||
type applyFunc func(*Chain, int64, factom.Entry) (txErr, err error) | ||||||||||||||
// pointer to chain, the entry itself, the eblock, and the position of entry in eblock's entrylist | ||||||||||||||
// if the entry was applied on its own, position and total are -1 | ||||||||||||||
type applyFunc func(*Chain, int64, factom.Entry, factom.EBlock, int) (txErr, err error) | ||||||||||||||
|
||||||||||||||
func (chain *Chain) Apply(dbKeyMR *factom.Bytes32, eb factom.EBlock) (err error) { | ||||||||||||||
// Ensure entire EBlock is applied atomically. | ||||||||||||||
|
@@ -57,20 +61,20 @@ func (chain *Chain) Apply(dbKeyMR *factom.Bytes32, eb factom.EBlock) (err error) | |||||||||||||
} | ||||||||||||||
|
||||||||||||||
// Insert each entry and attempt to apply it... | ||||||||||||||
for _, e := range eb.Entries { | ||||||||||||||
if _, err = chain.ApplyEntry(e); err != nil { | ||||||||||||||
for i, e := range eb.Entries { | ||||||||||||||
if _, err = chain.ApplyEntry(e, eb, i); err != nil { | ||||||||||||||
return | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
return | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
func (chain *Chain) ApplyEntry(e factom.Entry) (txErr, err error) { | ||||||||||||||
func (chain *Chain) ApplyEntry(e factom.Entry, eb factom.EBlock, pos int) (txErr, err error) { | ||||||||||||||
ei, err := entries.Insert(chain.Conn, e, chain.Head.Sequence) | ||||||||||||||
if err != nil { | ||||||||||||||
return | ||||||||||||||
} | ||||||||||||||
return chain.apply(chain, ei, e) | ||||||||||||||
return chain.apply(chain, ei, e, eb, pos) | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
var alwaysRollbackErr = fmt.Errorf("always rollback") | ||||||||||||||
|
@@ -110,8 +114,10 @@ func (chain *Chain) applyIssuance(ei int64, e factom.Entry) (issueErr, err error | |||||||||||||
} | ||||||||||||||
|
||||||||||||||
func (chain *Chain) setApplyFunc() { | ||||||||||||||
if !chain.Issuance.IsPopulated() { | ||||||||||||||
chain.apply = func(chain *Chain, ei int64, e factom.Entry) ( | ||||||||||||||
if !chain.Identity.IsPopulated() { | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not a reliable way to check if a chain is a pegnet chain. FAT chains can be tracked but not have a populated Identity yet. It would be better to set some flag, like the Chain.Type when the chain is first put into the ChainMap. |
||||||||||||||
chain.Type = fat.TypeFAT2 | ||||||||||||||
} else if !chain.Issuance.IsPopulated() { | ||||||||||||||
chain.apply = func(chain *Chain, ei int64, e factom.Entry, eb factom.EBlock, pos int) ( | ||||||||||||||
txErr, err error) { | ||||||||||||||
txErr, err = chain.applyIssuance(ei, e) | ||||||||||||||
return | ||||||||||||||
|
@@ -121,17 +127,23 @@ func (chain *Chain) setApplyFunc() { | |||||||||||||
// Adapt to match ApplyFunc. | ||||||||||||||
switch chain.Type { | ||||||||||||||
case fat0.Type: | ||||||||||||||
chain.apply = func(chain *Chain, ei int64, e factom.Entry) ( | ||||||||||||||
chain.apply = func(chain *Chain, ei int64, e factom.Entry, eb factom.EBlock, pos int) ( | ||||||||||||||
txErr, err error) { | ||||||||||||||
_, txErr, err = chain.ApplyFAT0Tx(ei, e) | ||||||||||||||
return | ||||||||||||||
} | ||||||||||||||
case fat1.Type: | ||||||||||||||
chain.apply = func(chain *Chain, ei int64, e factom.Entry) ( | ||||||||||||||
chain.apply = func(chain *Chain, ei int64, e factom.Entry, eb factom.EBlock, pos int) ( | ||||||||||||||
txErr, err error) { | ||||||||||||||
_, txErr, err = chain.ApplyFAT1Tx(ei, e) | ||||||||||||||
return | ||||||||||||||
} | ||||||||||||||
case fat.TypeFAT2: | ||||||||||||||
chain.apply = func(chain *Chain, ei int64, e factom.Entry, eb factom.EBlock, pos int) ( | ||||||||||||||
txErr, err error) { | ||||||||||||||
err = chain.ApplyFAT2OPR(ei, e, eb, pos) | ||||||||||||||
return | ||||||||||||||
} | ||||||||||||||
default: | ||||||||||||||
panic("invalid FAT type") | ||||||||||||||
} | ||||||||||||||
|
@@ -234,6 +246,67 @@ func (chain *Chain) ApplyFAT0Tx(ei int64, e factom.Entry) (tx *fat0.Transaction, | |||||||||||||
return | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
var tmp grader.BlockGrader | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this global is very very suspicious to me. Why can this not be created on the stack as its needed by functions? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This global seems more important than to be named There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
it can be made a chain struct variable once there is a dedicated pegnet chain but that would surpass its scope. the variable only needs to exist during the call of (db)chain.Apply() and would ideally be a local variable in there once the pegnet and fat chains are separated |
||||||||||||||
|
||||||||||||||
func (chain *Chain) ApplyFAT2OPR(ei int64, e factom.Entry, eb factom.EBlock, pos int) (err error) { | ||||||||||||||
if !eb.IsPopulated() || pos < 0 { // 'processing' entry | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This really seems like it should return an error. Also I believe it is a reasonable expectation that the caller has populated the EBlock. I think it would be best to not check if the eblock is populated and just let panics happen below here as this represents a serious integrity error with the code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. both "pending" entries and regular entries call the Apply function, but in the case of pending entries the entryblock passed into the function is Line 151 in 6d65886
it's not an error because at the time it is called, the entry cannot be validated. it can only be validated in the context of an eblock |
||||||||||||||
return | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
// beginning of every EBlock | ||||||||||||||
if pos == 0 { | ||||||||||||||
grader.InitLX() | ||||||||||||||
ver := uint8(1) | ||||||||||||||
if eb.Height >= 210330 { | ||||||||||||||
ver = uint8(2) | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
prev, err := pegnet.GetGrade(chain.Conn, eb.Sequence-1) | ||||||||||||||
if err != nil { | ||||||||||||||
return err | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
tmp, err = grader.NewGrader(ver, int32(eb.Height), prev) | ||||||||||||||
if err != nil { | ||||||||||||||
return err | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
// Every Entry | ||||||||||||||
var extids [][]byte | ||||||||||||||
for _, x := range e.ExtIDs { | ||||||||||||||
extids = append(extids, []byte(x)) | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see this is necessary for compatibility with the BlockGrader.AddOPR method. I'd rather see AddOPR be updated to accept []factom.Bytes, but for now this is ok. However if you are going to do this, properly make extids to the correct size: len(e.ExtIDs), and then set the values instead of using append. Also please follow the golang convention of using camel case everywhere and always capitalize both letters of ID, and use a descriptive variable name in the for loop instead of x.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
the grading module was written to be library independent |
||||||||||||||
} | ||||||||||||||
|
||||||||||||||
tmp.AddOPR(e.Hash[:], extids, []byte(e.Content)) | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. later, if you'd let me, I'd like to review this code as well. At the minimum I may be able to suggest a number of things to improve memory usage. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
sure but memory usage hasn't really been a problem. all the objects generated by the grader are ephemeral. they're discarded after a block is graded and only the relevant data is persisted |
||||||||||||||
|
||||||||||||||
//fmt.Println(pos, len(eb.Entries)) | ||||||||||||||
|
||||||||||||||
// After every EBlock | ||||||||||||||
if pos == len(eb.Entries)-1 { | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this pos variable is concerning to me. This variable seems to be important, but it has a very terse name. I'd like a more descriptive name for it at least. Also it feels a lot like something that should be considered part of the state. As state, I think it should probably be a member variable of the future pegnet chain type. This may also be a way to keep the Apply function signatures succinct while still allowing state data to be passed through without the engine having to deal with it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
"pos" is for position, which is the position of the entry being applied inside the eblock. it is the Lines 63 to 68 in 6d65886
|
||||||||||||||
graded := tmp.Grade() | ||||||||||||||
winners := graded.WinnersShortHashes() | ||||||||||||||
//fmt.Println("winners", winners) | ||||||||||||||
err := pegnet.InsertGrade(chain.Conn, eb, winners) | ||||||||||||||
if err != nil { | ||||||||||||||
return err | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
oprs := graded.Winners() | ||||||||||||||
if len(oprs) > 0 { | ||||||||||||||
for _, t := range oprs[0].OPR.GetOrderedAssetsUint() { | ||||||||||||||
err = pegnet.InsertRate(chain.Conn, eb, t.Name, t.Value) | ||||||||||||||
if err != nil { | ||||||||||||||
return err | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
tmp = nil | ||||||||||||||
graded = nil | ||||||||||||||
} | ||||||||||||||
return | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
func (chain *Chain) ApplyFAT1Tx(ei int64, e factom.Entry) (tx *fat1.Transaction, | ||||||||||||||
txErr, err error) { | ||||||||||||||
tx = fat1.NewTransaction(e) | ||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
// MIT License | ||
// | ||
// Copyright 2018 Canonical Ledgers, LLC | ||
// | ||
// Permission is hereby granted, free of charge, to any person obtaining a copy | ||
// of this software and associated documentation files (the "Software"), to | ||
// deal in the Software without restriction, including without limitation the | ||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||
// sell copies of the Software, and to permit persons to whom the Software is | ||
// furnished to do so, subject to the following conditions: | ||
// | ||
// The above copyright notice and this permission notice shall be included in | ||
// all copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
// IN THE SOFTWARE. | ||
|
||
// Package nftokens provides functions and SQL framents for working with the | ||
// "nf_tokens" table, which stores fat.NFToken with owner, creation id, and | ||
// metadata. | ||
|
||
package pegnet | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
|
||
"crawshaw.io/sqlite" | ||
"github.com/Factom-Asset-Tokens/factom" | ||
) | ||
|
||
const CreateTableGrade = `CREATE TABLE "pn_grade" ( | ||
"eb_seq" INTEGER NOT NULL, | ||
"winners" BLOB, | ||
|
||
UNIQUE("eb_seq") | ||
|
||
FOREIGN KEY("eb_seq") REFERENCES "eblocks" | ||
); | ||
` | ||
|
||
func InsertGrade(conn *sqlite.Conn, eb factom.EBlock, winners []string) error { | ||
data, err := json.Marshal(winners) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
stmt := conn.Prep(`INSERT INTO "pn_grade" | ||
("eb_seq", "winners") VALUES (?, ?);`) | ||
stmt.BindInt64(1, int64(eb.Sequence)) | ||
stmt.BindBytes(2, data) | ||
if _, err := stmt.Step(); err != nil { | ||
if sqlite.ErrCode(err) == sqlite.SQLITE_CONSTRAINT_UNIQUE { | ||
return fmt.Errorf("Grade{%d} already exists", eb.Sequence) | ||
} | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func GetGrade(conn *sqlite.Conn, seq uint32) ([]string, error) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would like to see the naming convention of SelectGrade be used here. An established convention in the factom package is that functions named Get... make network calls. |
||
stmt := conn.Prep(`SELECT "winners" FROM "pn_grade" WHERE "eb_seq" = ?;`) | ||
defer stmt.Reset() | ||
stmt.BindInt64(1, int64(seq)) | ||
hasRow, err := stmt.Step() | ||
if err != nil { | ||
return nil, err | ||
} | ||
if !hasRow { | ||
return nil, nil | ||
} | ||
|
||
buf := make([]byte, 2048) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is possible to get the exact size of the buffer using Stmt.ColumnLen:
|
||
read := stmt.ColumnBytes(0, buf) | ||
if read < 1 { | ||
return nil, nil | ||
} | ||
var winners []string | ||
err = json.Unmarshal(buf[:read], &winners) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return winners, nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// MIT License | ||
// | ||
// Copyright 2018 Canonical Ledgers, LLC | ||
// | ||
// Permission is hereby granted, free of charge, to any person obtaining a copy | ||
// of this software and associated documentation files (the "Software"), to | ||
// deal in the Software without restriction, including without limitation the | ||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||
// sell copies of the Software, and to permit persons to whom the Software is | ||
// furnished to do so, subject to the following conditions: | ||
// | ||
// The above copyright notice and this permission notice shall be included in | ||
// all copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
// IN THE SOFTWARE. | ||
|
||
// Package nftokens provides functions and SQL framents for working with the | ||
// "nf_tokens" table, which stores fat.NFToken with owner, creation id, and | ||
// metadata. | ||
|
||
package pegnet | ||
|
||
import ( | ||
"fmt" | ||
|
||
"crawshaw.io/sqlite" | ||
"github.com/Factom-Asset-Tokens/factom" | ||
) | ||
|
||
const CreateTableRate = `CREATE TABLE "pn_rate" ( | ||
"eb_seq" INTEGER NOT NULL, | ||
"token" TEXT, | ||
"value" INTEGER, | ||
|
||
UNIQUE("eb_seq", "token") | ||
|
||
FOREIGN KEY("eb_seq") REFERENCES "eblocks" | ||
); | ||
` | ||
|
||
func InsertRate(conn *sqlite.Conn, eb factom.EBlock, token string, value uint64) error { | ||
stmt := conn.Prep(`INSERT INTO "pn_rate" | ||
("eb_seq", "token", "value") VALUES (?, ?, ?);`) | ||
stmt.BindInt64(1, int64(eb.Sequence)) | ||
stmt.BindText(2, token) | ||
stmt.BindInt64(3, int64(value)) | ||
if _, err := stmt.Step(); err != nil { | ||
if sqlite.ErrCode(err) == sqlite.SQLITE_CONSTRAINT_UNIQUE { | ||
return fmt.Errorf("Rate{%d-%s} already exists", eb.Sequence, token) | ||
} | ||
return err | ||
} | ||
|
||
return nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,6 +32,7 @@ import ( | |
"github.com/Factom-Asset-Tokens/fatd/db/entries" | ||
"github.com/Factom-Asset-Tokens/fatd/db/metadata" | ||
"github.com/Factom-Asset-Tokens/fatd/db/nftokens" | ||
"github.com/Factom-Asset-Tokens/fatd/db/pegnet" | ||
) | ||
|
||
const ( | ||
|
@@ -43,7 +44,9 @@ const ( | |
addresses.CreateTableTransactions + | ||
nftokens.CreateTable + | ||
nftokens.CreateTableTransactions + | ||
metadata.CreateTable | ||
metadata.CreateTable + | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is fine for now but we will eventually want separate schemas. But for now it can wait. |
||
pegnet.CreateTableGrade + | ||
pegnet.CreateTableRate | ||
) | ||
|
||
// validateOrApplySchema compares schema with the database connected to by | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,8 +27,8 @@ import ( | |
"math" | ||
"sync" | ||
|
||
"github.com/Factom-Asset-Tokens/fatd/db" | ||
"github.com/Factom-Asset-Tokens/factom" | ||
"github.com/Factom-Asset-Tokens/fatd/db" | ||
"github.com/Factom-Asset-Tokens/fatd/flag" | ||
) | ||
|
||
|
@@ -133,6 +133,9 @@ func loadChains() (syncHeight uint32, err error) { | |
} | ||
}() | ||
|
||
oprChain := factom.NewBytes32FromString("a642a8674f46696cc47fdb6b65f9c87b2a19c5ea8123b3d2f0c13b6f33a9d5ef") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we are hard coding this chain ID into the engine, which I think is the right approach in general, why do we ever need to modify things like fat.ValidTokenNameIDs as that is only used on new unknown chains? Is there ever a place that fatd needs to scan for pegnet chains? |
||
flag.Whitelist = append(flag.Whitelist, *oprChain) | ||
|
||
// Set whitelisted chains to Tracked. | ||
for _, chainID := range flag.Whitelist { | ||
Chains.m[chainID] = Chain{ChainStatus: ChainStatusTracked} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,6 +31,9 @@ import ( | |
// ValidTokenNameIDs returns true if the nameIDs match the pattern for a valid | ||
// token chain. | ||
func ValidTokenNameIDs(nameIDs []factom.Bytes) bool { | ||
if IsPegNetOPR(nameIDs) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should create two separate sets of functions. Ones for validating FAT token chains, and ones for validating pegnet chains. that will greatly improve the clarity of the code. The engine and db packages can stitch these things together as needed. |
||
return true | ||
} | ||
if len(nameIDs) == 4 && len(nameIDs[1]) > 0 && | ||
string(nameIDs[0]) == "token" && string(nameIDs[2]) == "issuer" && | ||
factom.ValidIdentityChainID(nameIDs[3]) && | ||
|
@@ -40,6 +43,11 @@ func ValidTokenNameIDs(nameIDs []factom.Bytes) bool { | |
return false | ||
} | ||
|
||
func IsPegNetOPR(nameIDs []factom.Bytes) bool { | ||
return len(nameIDs) == 3 && string(nameIDs[0]) == "PegNet" && | ||
len(nameIDs[1]) > 0 && string(nameIDs[2]) == "OraclePriceRecords" | ||
} | ||
|
||
// NameIDs returns valid NameIDs | ||
func NameIDs(tokenID string, issuerChainID *factom.Bytes32) []factom.Bytes { | ||
return []factom.Bytes{ | ||
|
@@ -55,6 +63,11 @@ func ChainID(tokenID string, issuerChainID *factom.Bytes32) factom.Bytes32 { | |
|
||
func TokenIssuer(nameIDs []factom.Bytes) (string, *factom.Bytes32) { | ||
var identityChainID factom.Bytes32 | ||
|
||
if IsPegNetOPR(nameIDs) { | ||
return "", &identityChainID | ||
} | ||
|
||
copy(identityChainID[:], nameIDs[3]) | ||
return string(nameIDs[1]), &identityChainID | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -89,6 +89,9 @@ func (i Issuance) MarshalJSON() ([]byte, error) { | |
|
||
// NewIssuance returns an Issuance initialized with the given entry. | ||
func NewIssuance(entry factom.Entry) Issuance { | ||
if IsPegNetOPR(entry.ExtIDs) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does pegnet really have an issuance entry at all? If it does it's probably pretty different from this Issuance type. pegnet should probably just have its own data structures package that implements everything it needs independent of existing FAT types, except where there is a benefit to share. |
||
return Issuance{Type: TypeFAT2, Supply: 1, Entry: Entry{Entry: entry}} | ||
} | ||
return Issuance{Entry: Entry{Entry: entry}} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than trying to adapt the existing db.Chain type, I would prefer to see two Chain types, one for fat and one for pegnet. To the degree that they share some basic member variables, like the Conn and Pool and possibly the Head factom.EBlock, they could share a common type that they both embed. Then the engine needs to be modified to handle both chain types, either with interfaces or simply more bespoke processing functions if necessary.
Doing this will improve the separation of concern for sections of the code.
I actually prefer having duplicate code than tightly coupled code. It is easier to de-duplicate code than de-couple it.