Skip to content
This repository was archived by the owner on Apr 4, 2023. It is now read-only.

Commit f79a78f

Browse files
Merge pull request #71 from ava-labs/genesis-config
Support for Airdrops
2 parents 8c46686 + c22759e commit f79a78f

File tree

10 files changed

+973641
-31
lines changed

10 files changed

+973641
-31
lines changed

chain/codec.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ func init() {
3535
c.RegisterType(&Transaction{}),
3636
c.RegisterType(&StatefulBlock{}),
3737
c.RegisterType(&SpaceInfo{}),
38-
c.RegisterType(&Allocation{}),
38+
c.RegisterType(&CustomAllocation{}),
39+
c.RegisterType(&Airdrop{}),
3940
c.RegisterType(&Genesis{}),
4041
codecManager.RegisterCodec(codecVersion, c),
4142
)

chain/genesis.go

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,22 @@
44
package chain
55

66
import (
7+
"encoding/json"
78
"fmt"
89

910
"github.com/ava-labs/avalanchego/database"
1011
"github.com/ava-labs/avalanchego/utils/units"
1112
"github.com/ethereum/go-ethereum/common"
13+
"github.com/ethereum/go-ethereum/crypto"
1214
log "github.com/inconshreveable/log15"
1315
)
1416

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 {
1623
// Address strings are hex-formatted common.Address
1724
Address common.Address `serialize:"true" json:"address"`
1825
Balance uint64 `serialize:"true" json:"balance"`
@@ -55,8 +62,9 @@ type Genesis struct {
5562
MinBlockCost uint64 `serialize:"true" json:"minBlockCost"`
5663

5764
// 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"`
6068
}
6169

6270
func DefaultGenesis() *Genesis {
@@ -110,12 +118,36 @@ func (g *Genesis) Verify() error {
110118
return nil
111119
}
112120

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 {
115147
if err := SetBalance(db, alloc.Address, alloc.Balance); err != nil {
116148
return fmt.Errorf("%w: addr=%s, bal=%d", err, alloc.Address, alloc.Balance)
117149
}
118-
log.Debug("loaded genesis balance", "addr", alloc.Address, "balance", alloc.Balance)
150+
log.Debug("applied custom allocation", "addr", alloc.Address, "balance", alloc.Balance)
119151
}
120152
return nil
121153
}

chain/move_tx_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func TestMoveTx(t *testing.T) {
3939
defer db.Close()
4040

4141
g := DefaultGenesis()
42-
g.Allocations = []*Allocation{
42+
g.CustomAllocation = []*CustomAllocation{
4343
{
4444
Address: sender,
4545
Balance: 10000000,
@@ -50,7 +50,7 @@ func TestMoveTx(t *testing.T) {
5050
},
5151
// sender3 is not given any balance
5252
}
53-
if err := g.Load(db); err != nil {
53+
if err := g.Load(db, nil); err != nil {
5454
t.Fatal(err)
5555
}
5656

chain/transfer_tx_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func TestTransferTx(t *testing.T) {
3838
defer db.Close()
3939

4040
g := DefaultGenesis()
41-
g.Allocations = []*Allocation{
41+
g.CustomAllocation = []*CustomAllocation{
4242
{
4343
Address: sender,
4444
Balance: 10000000,
@@ -49,7 +49,7 @@ func TestTransferTx(t *testing.T) {
4949
},
5050
// sender3 is not given any balance
5151
}
52-
if err := g.Load(db); err != nil {
52+
if err := g.Load(db, nil); err != nil {
5353
t.Fatal(err)
5454
}
5555

chain/tx_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,14 @@ func TestTransactionErrInvalidSignature(t *testing.T) {
9595
}
9696
for i, tv := range tt {
9797
db := memdb.New()
98-
g.Allocations = []*Allocation{
98+
g.CustomAllocation = []*CustomAllocation{
9999
{
100100
Address: sender,
101101
Balance: 10000000,
102102
},
103103
// sender2 is not given any balance
104104
}
105-
if err := g.Load(db); err != nil {
105+
if err := g.Load(db, nil); err != nil {
106106
t.Fatal(err)
107107
}
108108
tx := tv.createTx()

cmd/spacescli/cmd/genesis.go

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@ import (
1818

1919
var (
2020
genesisFile string
21+
magic uint64
2122

2223
minPrice int64
2324
minBlockCost int64
2425
claimReward int64
2526
lifelineUnitReward int64
2627

27-
magic uint64
28+
airdropHash string
29+
airdropUnits uint64
2830
)
2931

3032
func init() {
@@ -58,10 +60,22 @@ func init() {
5860
-1,
5961
"seconds per unit of fee that will be rewarded in a lifeline transaction",
6062
)
63+
genesisCmd.PersistentFlags().StringVar(
64+
&airdropHash,
65+
"airdrop-hash",
66+
"",
67+
"hash of airdrop data",
68+
)
69+
genesisCmd.PersistentFlags().Uint64Var(
70+
&airdropUnits,
71+
"airdrop-units",
72+
0,
73+
"units to allocate to each airdrop address",
74+
)
6175
}
6276

6377
var genesisCmd = &cobra.Command{
64-
Use: "genesis [magic] [allocations file] [options]",
78+
Use: "genesis [magic] [custom allocations file] [options]",
6579
Short: "Creates a new genesis in the default location",
6680
PreRunE: func(cmd *cobra.Command, args []string) error {
6781
if len(args) != 2 {
@@ -97,17 +111,23 @@ func genesisFunc(cmd *cobra.Command, args []string) error {
97111
if lifelineUnitReward >= 0 {
98112
genesis.LifelineUnitReward = uint64(lifelineUnitReward)
99113
}
114+
if len(airdropHash) > 0 {
115+
genesis.AirdropHash = airdropHash
116+
if airdropUnits == 0 {
117+
return errors.New("non-zero airdrop units required")
118+
}
119+
genesis.AirdropUnits = airdropUnits
120+
}
100121

101122
a, err := os.ReadFile(args[1])
102123
if err != nil {
103124
return err
104125
}
105-
allocs := []*chain.Allocation{}
126+
allocs := []*chain.CustomAllocation{}
106127
if err := json.Unmarshal(a, &allocs); err != nil {
107128
return err
108129
}
109-
// Store hash instead
110-
genesis.Allocations = allocs
130+
genesis.CustomAllocation = allocs
111131

112132
b, err := json.Marshal(genesis)
113133
if err != nil {

0 commit comments

Comments
 (0)