Skip to content

Commit

Permalink
Fix comments after discussion
Browse files Browse the repository at this point in the history
  • Loading branch information
Kolezhniuk committed Dec 6, 2023
1 parent 274faf0 commit 87ce330
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 52 deletions.
2 changes: 1 addition & 1 deletion chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func ChainIDfromDID(did w3c.DID) (ChainID, error) {
func RegisterChainID(blockchain Blockchain, network NetworkID, chainID int) error {

k := fmt.Sprintf("%s:%s", blockchain, network)
if _, ok := chainIDs[k]; ok {
if existingChainID, ok := chainIDs[k]; ok && existingChainID != ChainID(chainID) {
return fmt.Errorf("chainID %s:%s already registered", blockchain, network)
}
chainIDs[k] = ChainID(chainID)
Expand Down
79 changes: 53 additions & 26 deletions did.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func GetDIDMethod(name string) (DIDMethod, error) {

method, ok := didMethods[DIDMethod(name)]
if !ok {
return DIDMethodOther, fmt.Errorf("DID method %s not found", name)
return DIDMethodOther, fmt.Errorf("DID method '%s' not found", name)
}
return method, nil
}
Expand Down Expand Up @@ -85,29 +85,31 @@ var blockchains = map[Blockchain]Blockchain{
func GetBlockchain(name string) (Blockchain, error) {
blockchain, ok := blockchains[Blockchain(name)]
if !ok {
return UnknownChain, fmt.Errorf("blockchain %s not found", name)
return UnknownChain, fmt.Errorf("blockchain '%s' not found", name)
}
return blockchain, nil
}

// RegisterBlockchain registers new blockchain
func RegisterBlockchain(b Blockchain) error {
blockchains[b] = b
return nil
}

// NetworkID is method specific network identifier
type NetworkID string

const (
// Main is main network
Main NetworkID = "main"

// Mumbai is polygon mumbai test network
Mumbai NetworkID = "mumbai"

// Goerli is ethereum goerli test network
Goerli NetworkID = "goerli" // goerli
// Sepolia is ethereum Sepolia test network
Sepolia NetworkID = "sepolia"

// Test is test network
Test NetworkID = "test"

// UnknownNetwork is used when it's not possible to retrieve network from identifier
UnknownNetwork NetworkID = "unknown"
// NoNetwork should be used for readonly identity to build readonly flag
Expand All @@ -128,11 +130,17 @@ var networks = map[NetworkID]NetworkID{
func GetNetwork(name string) (NetworkID, error) {
network, ok := networks[NetworkID(name)]
if !ok {
return UnknownNetwork, fmt.Errorf("network %s not found", name)
return UnknownNetwork, fmt.Errorf("network '%s' not found", name)
}
return network, nil
}

// RegisterNetwork registers new network
func RegisterNetwork(n NetworkID) error {
networks[n] = n
return nil
}

// DIDMethodByte did method flag representation
var DIDMethodByte = map[DIDMethod]byte{
DIDMethodIden3: 0b00000001,
Expand All @@ -142,12 +150,17 @@ var DIDMethodByte = map[DIDMethod]byte{

// RegisterDIDMethod registers new DID method with byte flag
func RegisterDIDMethod(m DIDMethod, b byte) error {
didMethods[m] = m

if _, ok := DIDMethodByte[m]; ok {
if existingByte, ok := DIDMethodByte[m]; ok && existingByte != b {
return fmt.Errorf("DID method %s already registered", m)
}

max := DIDMethodByte[DIDMethodOther]
if b >= max {
return fmt.Errorf("Can't register DID method byte: current %b, maximum byte allowed: %b", b, max-1)
}

didMethods[m] = m
DIDMethodByte[m] = b

return nil
Expand Down Expand Up @@ -198,40 +211,54 @@ type DIDMethodNetworkParams struct {
Blockchain Blockchain
Network NetworkID
NetworkFlag byte
chainID *int
methodByte *byte
}

type registrationOptions struct {
chainID *int
methodByte *byte
}

// RegistrationOptions is a type for DID method network options
type RegistrationOptions func(params *DIDMethodNetworkParams)
type RegistrationOptions func(params *registrationOptions)

// WithChainID registers new chain ID method with byte flag
func WithChainID(chainID int) RegistrationOptions {
return func(params *DIDMethodNetworkParams) {
params.chainID = &chainID
return func(opts *registrationOptions) {
opts.chainID = &chainID
}
}

// WithDIDMethodByte registers new DID method with byte flag
func WithDIDMethodByte(methodByte byte) RegistrationOptions {
return func(params *DIDMethodNetworkParams) {
params.methodByte = &methodByte
return func(opts *registrationOptions) {
opts.methodByte = &methodByte
}
}

// RegisterDIDMethodNetwork registers new DID method network
func RegisterDIDMethodNetwork(params DIDMethodNetworkParams, opts ...RegistrationOptions) error {

var err error
o := registrationOptions{}
for _, opt := range opts {
opt(&params)
opt(&o)
}

b := params.Blockchain
n := params.Network
m := params.Method
blockchains[b] = b
networks[n] = n

if params.methodByte != nil {
err := RegisterDIDMethod(m, *params.methodByte)
err = RegisterBlockchain(b)
if err != nil {
return err
}

err = RegisterNetwork(n)
if err != nil {
return err
}

if o.methodByte != nil {
err = RegisterDIDMethod(m, *o.methodByte)
if err != nil {
return err
}
Expand All @@ -243,15 +270,15 @@ func RegisterDIDMethodNetwork(params DIDMethodNetworkParams, opts ...Registratio
DIDMethodNetwork[m] = map[DIDNetworkFlag]byte{}
}

if params.chainID != nil {
err := RegisterChainID(b, n, *params.chainID)
if o.chainID != nil {
err = RegisterChainID(b, n, *o.chainID)
if err != nil {
return err
}
}

if _, ok := DIDMethodNetwork[m][flg]; ok {
return fmt.Errorf("DID method network %s with blockchain %s and network %s already registered",
if existed, ok := DIDMethodNetwork[m][flg]; ok && existed != params.NetworkFlag {
return fmt.Errorf("DID method network '%s' with blockchain '%s' and network '%s' already registered",
m, b, n)
}

Expand Down
103 changes: 78 additions & 25 deletions did_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,14 +380,10 @@ func ethAddrFromHex(ea string) [20]byte {
return ethAddr
}

func strPtr(s string) *string {
return &s
}
func TestDID_Custom_Parse_DID(t *testing.T) {
func TestCustomDIDRegistration(t *testing.T) {
testCases := []struct {
Description string
Data DIDMethodNetworkParams
ErrorMsg *string
opts []RegistrationOptions
}{
{
Expand All @@ -411,46 +407,44 @@ func TestDID_Custom_Parse_DID(t *testing.T) {
opts: []RegistrationOptions{WithChainID(102), WithDIDMethodByte(0b00000100)},
},
{
Description: "register network to existing did method",
Description: "register the same new did method network",
Data: DIDMethodNetworkParams{
Method: DIDMethodIden3,
Method: "method",
Blockchain: "chain",
Network: Test,
NetworkFlag: 0b01000000 | 0b00000011,
Network: "network",
NetworkFlag: 0b0001_0001,
},
opts: []RegistrationOptions{WithChainID(103)},
opts: []RegistrationOptions{WithChainID(102), WithDIDMethodByte(0b00000100)},
},
{
Description: "register one more network to existing did method",
Description: "register network to existing did method",
Data: DIDMethodNetworkParams{
Method: DIDMethodIden3,
Blockchain: ReadOnly,
Network: "network",
Blockchain: "chain",
Network: Test,
NetworkFlag: 0b01000000 | 0b00000011,
},
opts: []RegistrationOptions{WithChainID(104)},
opts: []RegistrationOptions{WithChainID(103)},
},
{
Description: "register already registered did method network",
Description: "register network to existing did method and chainId",
Data: DIDMethodNetworkParams{
Method: DIDMethodIden3,
Blockchain: ReadOnly,
Network: "network",
NetworkFlag: 0b01000000 | 0b00000011,
Network: NoNetwork,
NetworkFlag: 0b00000000,
},
ErrorMsg: strPtr("DID method network iden3 with blockchain readonly and network network already registered"),
opts: []RegistrationOptions{WithChainID(103)},
},
{
Description: "register exited chain",
Description: "register one more network to existing did method",
Data: DIDMethodNetworkParams{
Method: DIDMethodIden3,
Blockchain: ReadOnly,
Network: "network",
NetworkFlag: 0b01000000 | 0b00000011,
},
opts: []RegistrationOptions{WithChainID(104)},

ErrorMsg: strPtr("chainID readonly:network already registered"),
},
{
Description: "register known chain id to new did method",
Expand All @@ -467,10 +461,6 @@ func TestDID_Custom_Parse_DID(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.Description, func(t *testing.T) {
err := RegisterDIDMethodNetwork(tc.Data, tc.opts...)
if tc.ErrorMsg != nil {
require.EqualError(t, err, *tc.ErrorMsg)
return
}
require.NoError(t, err)
})
}
Expand Down Expand Up @@ -498,3 +488,66 @@ func TestDID_Custom_Parse_DID(t *testing.T) {
require.Equal(t, NetworkID("network"), networkID)

}

func TestCustomDIDRegistration_Negative(t *testing.T) {
testCases := []struct {
Description string
Data DIDMethodNetworkParams
opts []RegistrationOptions
err string
}{

{
Description: "try to overwrite existing chain id",
Data: DIDMethodNetworkParams{
Method: DIDMethodIden3,
Blockchain: Polygon,
Network: Mumbai,
NetworkFlag: 0b0001_0001,
},
opts: []RegistrationOptions{WithChainID(1)},
err: "chainID polygon:mumbai already registered",
},
{
Description: "try to overwrite existing DID method byte",
Data: DIDMethodNetworkParams{
Method: DIDMethodIden3,
Blockchain: Ethereum,
Network: Main,
NetworkFlag: 0b00100000 | 0b00000001,
},
opts: []RegistrationOptions{WithChainID(1), WithDIDMethodByte(0b00000010)},
err: "DID method iden3 already registered",
},
{
Description: "try to write max did method byte",
Data: DIDMethodNetworkParams{
Method: "method33",
Blockchain: Ethereum,
Network: Main,
NetworkFlag: 0b00100000 | 0b00000001,
},
opts: []RegistrationOptions{WithChainID(1), WithDIDMethodByte(0b11111111)},
err: "Can't register DID method byte: current 11111111, maximum byte allowed: 11111110",
},
{
Description: "try to rewrite existing DID Method Network Flag",
Data: DIDMethodNetworkParams{
Method: DIDMethodIden3,
Blockchain: Ethereum,
Network: Main,
NetworkFlag: 0b00100000 | 0b00000011,
},
opts: nil,
err: "DID method network 'iden3' with blockchain 'eth' and network 'main' already registered",
},
}

for _, tc := range testCases {
t.Run(tc.Description, func(t *testing.T) {
err := RegisterDIDMethodNetwork(tc.Data, tc.opts...)
require.EqualError(t, err, tc.err)
})
}

}

0 comments on commit 87ce330

Please sign in to comment.