Fixed non-determinism in genesis creation

This commit is contained in:
StephenButtolph 2020-04-03 15:50:29 -04:00
parent 4050be294b
commit dce704e8f0
4 changed files with 133 additions and 65 deletions

View File

@ -6,6 +6,7 @@ package genesis
import ( import (
"testing" "testing"
"github.com/ava-labs/gecko/ids"
"github.com/ava-labs/gecko/vms/avm" "github.com/ava-labs/gecko/vms/avm"
"github.com/ava-labs/gecko/vms/evm" "github.com/ava-labs/gecko/vms/evm"
"github.com/ava-labs/gecko/vms/platformvm" "github.com/ava-labs/gecko/vms/platformvm"
@ -106,9 +107,74 @@ func TestAliases(t *testing.T) {
} }
func TestGenesis(t *testing.T) { func TestGenesis(t *testing.T) {
genesisBytes, _ := Genesis(LocalID) genesisBytes, err := Genesis(LocalID)
if err != nil {
t.Fatal(err)
}
genesis := platformvm.Genesis{} genesis := platformvm.Genesis{}
if err := platformvm.Codec.Unmarshal(genesisBytes, &genesis); err != nil { if err := platformvm.Codec.Unmarshal(genesisBytes, &genesis); err != nil {
t.Fatal(err) t.Fatal(err)
} }
} }
func TestVMGenesis(t *testing.T) {
tests := []struct {
networkID uint32
vmID ids.ID
expectedID string
}{
{
networkID: CascadeID,
vmID: avm.ID,
expectedID: "2aJ8wzhzbDWB9utBtA4h1oqcrXJRWfj8RakJfJSo3M16i3Vk5N",
},
{
networkID: LocalID,
vmID: avm.ID,
expectedID: "4R5p2RXDGLqaifZE4hHWH9owe34pfoBULn1DrQTWivjg8o4aH",
},
}
for _, test := range tests {
genesisTx, err := VMGenesis(test.networkID, test.vmID)
if err != nil {
t.Fatal(err)
}
if result := genesisTx.ID().String(); test.expectedID != result {
t.Fatalf("%s genesisID with networkID %d was expected to be %s but was %s",
test.vmID,
test.networkID,
test.expectedID,
result)
}
}
}
func TestAVAAssetID(t *testing.T) {
tests := []struct {
networkID uint32
expectedID string
}{
{
networkID: CascadeID,
expectedID: "4AXHxutuTMNdMqLkniJhmX5M1dgtVx3Gs1LNfJZcnE3P5ewSp",
},
{
networkID: LocalID,
expectedID: "n8XH5JY1EX5VYqDeAhB4Zd4GKxi9UNQy6oPpMsCAj1Q6xkiiL",
},
}
for _, test := range tests {
avaID, err := AVAAssetID(test.networkID)
if err != nil {
t.Fatal(err)
}
if result := avaID.String(); test.expectedID != result {
t.Fatalf("AVA assetID with networkID %d was expected to be %s but was %s",
test.networkID,
test.expectedID,
result)
}
}
}

View File

@ -38,7 +38,9 @@ func (sr *ChainRouter) AddChain(chain *handler.Handler) {
sr.lock.Lock() sr.lock.Lock()
defer sr.lock.Unlock() defer sr.lock.Unlock()
sr.chains[chain.Context().ChainID.Key()] = chain chainID := chain.Context().ChainID
sr.log.Debug("Adding %s to the routing table", chainID)
sr.chains[chainID.Key()] = chain
} }
// RemoveChain removes the specified chain so that incoming // RemoveChain removes the specified chain so that incoming

View File

@ -77,78 +77,78 @@ func (*StaticService) BuildGenesis(_ *http.Request, args *BuildGenesisArgs, repl
Denomination: byte(assetDefinition.Denomination), Denomination: byte(assetDefinition.Denomination),
}, },
} }
for assetType, initialStates := range assetDefinition.InitialState { if len(assetDefinition.InitialState) > 0 {
switch assetType { initialState := &InitialState{
case "fixedCap": FxID: 0, // TODO: Should lookup secp256k1fx FxID
initialState := &InitialState{ }
FxID: 0, // TODO: Should lookup secp256k1fx FxID for assetType, initialStates := range assetDefinition.InitialState {
} switch assetType {
for _, state := range initialStates { case "fixedCap":
b, err := json.Marshal(state) for _, state := range initialStates {
if err != nil { b, err := json.Marshal(state)
return err if err != nil {
} return err
holder := Holder{} }
if err := json.Unmarshal(b, &holder); err != nil { holder := Holder{}
return err if err := json.Unmarshal(b, &holder); err != nil {
} return err
cb58 := formatting.CB58{} }
if err := cb58.FromString(holder.Address); err != nil {
return err
}
addr, err := ids.ToShortID(cb58.Bytes)
if err != nil {
return err
}
initialState.Outs = append(initialState.Outs, &secp256k1fx.TransferOutput{
Amt: uint64(holder.Amount),
OutputOwners: secp256k1fx.OutputOwners{
Threshold: 1,
Addrs: []ids.ShortID{addr},
},
})
}
initialState.Sort(c)
asset.States = append(asset.States, initialState)
case "variableCap":
initialState := &InitialState{
FxID: 0, // TODO: Should lookup secp256k1fx FxID
}
for _, state := range initialStates {
b, err := json.Marshal(state)
if err != nil {
return err
}
owners := Owners{}
if err := json.Unmarshal(b, &owners); err != nil {
return err
}
out := &secp256k1fx.MintOutput{
OutputOwners: secp256k1fx.OutputOwners{
Threshold: 1,
},
}
for _, address := range owners.Minters {
cb58 := formatting.CB58{} cb58 := formatting.CB58{}
if err := cb58.FromString(address); err != nil { if err := cb58.FromString(holder.Address); err != nil {
return err return err
} }
addr, err := ids.ToShortID(cb58.Bytes) addr, err := ids.ToShortID(cb58.Bytes)
if err != nil { if err != nil {
return err return err
} }
out.Addrs = append(out.Addrs, addr) initialState.Outs = append(initialState.Outs, &secp256k1fx.TransferOutput{
Amt: uint64(holder.Amount),
OutputOwners: secp256k1fx.OutputOwners{
Threshold: 1,
Addrs: []ids.ShortID{addr},
},
})
} }
out.Sort() case "variableCap":
initialState := &InitialState{
FxID: 0, // TODO: Should lookup secp256k1fx FxID
}
for _, state := range initialStates {
b, err := json.Marshal(state)
if err != nil {
return err
}
owners := Owners{}
if err := json.Unmarshal(b, &owners); err != nil {
return err
}
initialState.Outs = append(initialState.Outs, out) out := &secp256k1fx.MintOutput{
OutputOwners: secp256k1fx.OutputOwners{
Threshold: 1,
},
}
for _, address := range owners.Minters {
cb58 := formatting.CB58{}
if err := cb58.FromString(address); err != nil {
return err
}
addr, err := ids.ToShortID(cb58.Bytes)
if err != nil {
return err
}
out.Addrs = append(out.Addrs, addr)
}
out.Sort()
initialState.Outs = append(initialState.Outs, out)
}
default:
return errUnknownAssetType
} }
initialState.Sort(c)
asset.States = append(asset.States, initialState)
default:
return errUnknownAssetType
} }
initialState.Sort(c)
asset.States = append(asset.States, initialState)
} }
asset.Sort() asset.Sort()
g.Txs = append(g.Txs, &asset) g.Txs = append(g.Txs, &asset)

View File

@ -137,8 +137,8 @@ func (*StaticService) BuildGenesis(_ *http.Request, args *BuildGenesisArgs, repl
return errAccountHasNoValue return errAccountHasNoValue
} }
accounts = append(accounts, newAccount( accounts = append(accounts, newAccount(
account.Address, // ID account.Address, // ID
0, // nonce 0, // nonce
uint64(account.Balance), // balance uint64(account.Balance), // balance
)) ))
} }