|
4 | 4 | package chain |
5 | 5 |
|
6 | 6 | import ( |
| 7 | + "encoding/json" |
7 | 8 | "fmt" |
8 | 9 |
|
9 | 10 | "github.com/ava-labs/avalanchego/database" |
10 | 11 | "github.com/ava-labs/avalanchego/utils/units" |
11 | 12 | "github.com/ethereum/go-ethereum/common" |
| 13 | + "github.com/ethereum/go-ethereum/crypto" |
12 | 14 | log "github.com/inconshreveable/log15" |
13 | 15 | ) |
14 | 16 |
|
15 | | -type Allocation struct { |
| 17 | +type Airdrop struct { |
| 18 | + // Address strings are hex-formatted common.Address |
| 19 | + Address common.Address `serialize:"true" json:"address"` |
| 20 | +} |
| 21 | + |
| 22 | +type CustomAllocation struct { |
16 | 23 | // Address strings are hex-formatted common.Address |
17 | 24 | Address common.Address `serialize:"true" json:"address"` |
18 | 25 | Balance uint64 `serialize:"true" json:"balance"` |
@@ -55,8 +62,9 @@ type Genesis struct { |
55 | 62 | MinBlockCost uint64 `serialize:"true" json:"minBlockCost"` |
56 | 63 |
|
57 | 64 | // Allocations |
58 | | - // TODO: move to a hash and use external file to avoid 1MB limit |
59 | | - Allocations []*Allocation `serialize:"true" json:"allocations"` |
| 65 | + CustomAllocation []*CustomAllocation `serialize:"true" json:"customAllocation"` |
| 66 | + AirdropHash string `serialize:"true" json:"airdropHash"` |
| 67 | + AirdropUnits uint64 `serialize:"true" json:"airdropUnits"` |
60 | 68 | } |
61 | 69 |
|
62 | 70 | func DefaultGenesis() *Genesis { |
@@ -110,12 +118,36 @@ func (g *Genesis) Verify() error { |
110 | 118 | return nil |
111 | 119 | } |
112 | 120 |
|
113 | | -func (g *Genesis) Load(db database.KeyValueWriter) error { |
114 | | - for _, alloc := range g.Allocations { |
| 121 | +func (g *Genesis) Load(db database.KeyValueWriter, airdropData []byte) error { |
| 122 | + if len(g.AirdropHash) > 0 { |
| 123 | + h := common.BytesToHash(crypto.Keccak256(airdropData)).Hex() |
| 124 | + if g.AirdropHash != h { |
| 125 | + return fmt.Errorf("expected standard allocation %s but got %s", g.AirdropHash, h) |
| 126 | + } |
| 127 | + |
| 128 | + standardAllocation := []*Airdrop{} |
| 129 | + if err := json.Unmarshal(airdropData, &standardAllocation); err != nil { |
| 130 | + return err |
| 131 | + } |
| 132 | + |
| 133 | + for _, alloc := range standardAllocation { |
| 134 | + if err := SetBalance(db, alloc.Address, g.AirdropUnits); err != nil { |
| 135 | + return fmt.Errorf("%w: addr=%s, bal=%d", err, alloc.Address, g.AirdropUnits) |
| 136 | + } |
| 137 | + } |
| 138 | + log.Debug( |
| 139 | + "applied airdrop allocation", |
| 140 | + "hash", h, "addrs", len(standardAllocation), "balance", g.AirdropUnits, |
| 141 | + ) |
| 142 | + } |
| 143 | + |
| 144 | + // Do custom allocation last in case an address shows up in standard |
| 145 | + // allocation |
| 146 | + for _, alloc := range g.CustomAllocation { |
115 | 147 | if err := SetBalance(db, alloc.Address, alloc.Balance); err != nil { |
116 | 148 | return fmt.Errorf("%w: addr=%s, bal=%d", err, alloc.Address, alloc.Balance) |
117 | 149 | } |
118 | | - log.Debug("loaded genesis balance", "addr", alloc.Address, "balance", alloc.Balance) |
| 150 | + log.Debug("applied custom allocation", "addr", alloc.Address, "balance", alloc.Balance) |
119 | 151 | } |
120 | 152 | return nil |
121 | 153 | } |
0 commit comments