github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/genesis/spec/presets.go (about)

     1  package spec
     2  
     3  import (
     4  	"sort"
     5  
     6  	"github.com/hyperledger/burrow/acm/balance"
     7  	"github.com/hyperledger/burrow/permission"
     8  )
     9  
    10  // Files here can be used as starting points for building various 'chain types' but are otherwise
    11  // a fairly unprincipled collection of GenesisSpecs that we find useful in testing and development
    12  
    13  func FullAccount(name string) GenesisSpec {
    14  	// Inheriting from the arbitrary figures used by monax tool for now
    15  	amount := uint64(99999999999999)
    16  	Power := uint64(9999999999)
    17  	return GenesisSpec{
    18  		Accounts: []TemplateAccount{{
    19  			Name:        name,
    20  			Amounts:     balance.New().Native(amount).Power(Power),
    21  			Permissions: []string{permission.AllString},
    22  		},
    23  		},
    24  	}
    25  }
    26  
    27  func RootAccount(name string) GenesisSpec {
    28  	// Inheriting from the arbitrary figures used by monax tool for now
    29  	amount := uint64(99999999999999)
    30  	return GenesisSpec{
    31  		Accounts: []TemplateAccount{{
    32  			Name:        name,
    33  			Amounts:     balance.New().Native(amount),
    34  			Permissions: []string{permission.AllString},
    35  		},
    36  		},
    37  	}
    38  }
    39  
    40  func ParticipantAccount(name string) GenesisSpec {
    41  	// Inheriting from the arbitrary figures used by monax tool for now
    42  	amount := uint64(9999999999)
    43  	return GenesisSpec{
    44  		Accounts: []TemplateAccount{{
    45  			Name:    name,
    46  			Amounts: balance.New().Native(amount),
    47  			Permissions: []string{permission.SendString, permission.CallString, permission.NameString,
    48  				permission.HasRoleString, permission.ProposalString, permission.InputString},
    49  		}},
    50  	}
    51  }
    52  
    53  func DeveloperAccount(name string) GenesisSpec {
    54  	// Inheriting from the arbitrary figures used by monax tool for now
    55  	amount := uint64(9999999999)
    56  	return GenesisSpec{
    57  		Accounts: []TemplateAccount{{
    58  			Name:    name,
    59  			Amounts: balance.New().Native(amount),
    60  			Permissions: []string{permission.SendString, permission.CallString, permission.CreateContractString,
    61  				permission.CreateAccountString, permission.NameString, permission.HasRoleString,
    62  				permission.RemoveRoleString, permission.ProposalString, permission.InputString},
    63  		}},
    64  	}
    65  }
    66  
    67  func ValidatorAccount(name string) GenesisSpec {
    68  	// Inheriting from the arbitrary figures used by monax tool for now
    69  	amount := uint64(9999999999)
    70  	Power := amount - 1
    71  	return GenesisSpec{
    72  		Accounts: []TemplateAccount{{
    73  			Name:        name,
    74  			Amounts:     balance.New().Native(amount).Power(Power),
    75  			Permissions: []string{permission.BondString},
    76  		}},
    77  	}
    78  }
    79  
    80  func MergeGenesisSpecs(genesisSpecs ...GenesisSpec) GenesisSpec {
    81  	mergedGenesisSpec := GenesisSpec{}
    82  	// We will deduplicate and merge global permissions flags
    83  	permSet := make(map[string]struct{})
    84  
    85  	for _, genesisSpec := range genesisSpecs {
    86  		// We'll overwrite chain name for later specs
    87  		if genesisSpec.ChainName != "" {
    88  			mergedGenesisSpec.ChainName = genesisSpec.ChainName
    89  		}
    90  		// Take the max genesis time
    91  		if mergedGenesisSpec.GenesisTime == nil ||
    92  			(genesisSpec.GenesisTime != nil && genesisSpec.GenesisTime.After(*mergedGenesisSpec.GenesisTime)) {
    93  			mergedGenesisSpec.GenesisTime = genesisSpec.GenesisTime
    94  		}
    95  
    96  		for _, permString := range genesisSpec.GlobalPermissions {
    97  			permSet[permString] = struct{}{}
    98  		}
    99  
   100  		mergedGenesisSpec.Salt = append(mergedGenesisSpec.Salt, genesisSpec.Salt...)
   101  		mergedGenesisSpec.Accounts = mergeAccounts(mergedGenesisSpec.Accounts, genesisSpec.Accounts)
   102  	}
   103  
   104  	mergedGenesisSpec.GlobalPermissions = make([]string, 0, len(permSet))
   105  
   106  	for permString := range permSet {
   107  		mergedGenesisSpec.GlobalPermissions = append(mergedGenesisSpec.GlobalPermissions, permString)
   108  	}
   109  
   110  	// Make sure merged GenesisSpec is deterministic on inputs
   111  	sort.Strings(mergedGenesisSpec.GlobalPermissions)
   112  
   113  	return mergedGenesisSpec
   114  }
   115  
   116  // Merge accounts by adding to base list or updating previously named account
   117  func mergeAccounts(bases, overrides []TemplateAccount) []TemplateAccount {
   118  	indexOfBase := make(map[string]int, len(bases))
   119  	for i, ta := range bases {
   120  		if ta.Name != "" {
   121  			indexOfBase[ta.Name] = i
   122  		}
   123  	}
   124  
   125  	for _, override := range overrides {
   126  		if override.Name != "" {
   127  			if i, ok := indexOfBase[override.Name]; ok {
   128  				bases[i] = mergeAccount(bases[i], override)
   129  				continue
   130  			}
   131  		}
   132  		bases = append(bases, override)
   133  	}
   134  	return bases
   135  }
   136  
   137  func mergeAccount(base, override TemplateAccount) TemplateAccount {
   138  	if override.Address != nil {
   139  		base.Address = override.Address
   140  	}
   141  	if override.PublicKey != nil {
   142  		base.PublicKey = override.PublicKey
   143  	}
   144  	if override.Name != "" {
   145  		base.Name = override.Name
   146  	}
   147  
   148  	base.Amounts = base.Balances().Sum(override.Balances())
   149  
   150  	base.Permissions = mergeStrings(base.Permissions, override.Permissions)
   151  	base.Roles = mergeStrings(base.Roles, override.Roles)
   152  	return base
   153  }
   154  
   155  func mergeStrings(as, bs []string) []string {
   156  	var strs []string
   157  	strSet := make(map[string]struct{})
   158  	for _, a := range as {
   159  		strSet[a] = struct{}{}
   160  	}
   161  	for _, b := range bs {
   162  		strSet[b] = struct{}{}
   163  	}
   164  	for str := range strSet {
   165  		strs = append(strs, str)
   166  	}
   167  	sort.Strings(strs)
   168  	return strs
   169  }