Skip to content

Commit 90ec163

Browse files
committed
refactor: genesis building logic in avm and platformvm
1 parent 7d44651 commit 90ec163

File tree

7 files changed

+111
-187
lines changed

7 files changed

+111
-187
lines changed

genesis/genesis.go

+2-4
Original file line numberDiff line numberDiff line change
@@ -346,8 +346,7 @@ func FromConfig(config *Config) ([]byte, ids.ID, error) {
346346
}
347347
avmReply := avm.BuildGenesisReply{}
348348

349-
avmSS := avm.CreateStaticService()
350-
err := avmSS.BuildGenesis(nil, &avmArgs, &avmReply)
349+
err := avm.BuildGenesis(&avmArgs, &avmReply)
351350
if err != nil {
352351
return nil, ids.Empty, err
353352
}
@@ -487,8 +486,7 @@ func FromConfig(config *Config) ([]byte, ids.ID, error) {
487486
}
488487

489488
platformvmReply := api.BuildGenesisReply{}
490-
platformvmSS := api.StaticService{}
491-
if err := platformvmSS.BuildGenesis(nil, &platformvmArgs, &platformvmReply); err != nil {
489+
if err := api.BuildGenesis(&platformvmArgs, &platformvmReply); err != nil {
492490
return nil, ids.Empty, fmt.Errorf("problem while building platform chain's genesis state: %w", err)
493491
}
494492

vms/avm/environment_test.go

+1-3
Original file line numberDiff line numberDiff line change
@@ -227,10 +227,8 @@ func buildGenesisTest(tb testing.TB) []byte {
227227
func buildGenesisTestWithArgs(tb testing.TB, args *BuildGenesisArgs) []byte {
228228
require := require.New(tb)
229229

230-
ss := CreateStaticService()
231-
232230
reply := BuildGenesisReply{}
233-
require.NoError(ss.BuildGenesis(nil, args, &reply))
231+
require.NoError(BuildGenesis(args, &reply))
234232

235233
b, err := formatting.Decode(reply.Encoding, reply.Bytes)
236234
require.NoError(err)

vms/avm/static_service.go renamed to vms/avm/genesis_builder.go

+1-9
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"encoding/json"
88
"errors"
99
"fmt"
10-
"net/http"
1110

1211
"github.com/ava-labs/avalanchego/ids"
1312
"github.com/ava-labs/avalanchego/utils"
@@ -46,13 +45,6 @@ var (
4645
_ verify.Verifiable = (*propertyfx.Credential)(nil)
4746
)
4847

49-
// StaticService defines the base service for the asset vm
50-
type StaticService struct{}
51-
52-
func CreateStaticService() *StaticService {
53-
return &StaticService{}
54-
}
55-
5648
// BuildGenesisArgs are arguments for BuildGenesis
5749
type BuildGenesisArgs struct {
5850
NetworkID avajson.Uint32 `json:"networkID"`
@@ -88,7 +80,7 @@ type BuildGenesisReply struct {
8880

8981
// BuildGenesis returns the UTXOs such that at least one address in [args.Addresses] is
9082
// referenced in the UTXO.
91-
func (*StaticService) BuildGenesis(_ *http.Request, args *BuildGenesisArgs, reply *BuildGenesisReply) error {
83+
func BuildGenesis(args *BuildGenesisArgs, reply *BuildGenesisReply) error {
9284
parser, err := txs.NewParser(
9385
[]fxs.Fx{
9486
&secp256k1fx.Fx{},

vms/avm/genesis_builder_test.go

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
2+
// See the file LICENSE for licensing terms.
3+
4+
package avm
5+
6+
import (
7+
"testing"
8+
9+
"github.com/stretchr/testify/require"
10+
11+
"github.com/ava-labs/avalanchego/ids"
12+
"github.com/ava-labs/avalanchego/utils/constants"
13+
"github.com/ava-labs/avalanchego/utils/formatting"
14+
"github.com/ava-labs/avalanchego/utils/formatting/address"
15+
"github.com/ava-labs/avalanchego/utils/json"
16+
)
17+
18+
var addrStrArray = []string{
19+
"A9bTQjfYGBFK3JPRJqF2eh3JYL7cHocvy",
20+
"6mxBGnjGDCKgkVe7yfrmvMA7xE7qCv3vv",
21+
"6ncQ19Q2U4MamkCYzshhD8XFjfwAWFzTa",
22+
"Jz9ayEDt7dx9hDx45aXALujWmL9ZUuqe7",
23+
}
24+
25+
func TestBuildGenesis(t *testing.T) {
26+
require := require.New(t)
27+
28+
addrMap := map[string]string{}
29+
for _, addrStr := range addrStrArray {
30+
addr, err := ids.ShortFromString(addrStr)
31+
require.NoError(err)
32+
addrMap[addrStr], err = address.FormatBech32(constants.UnitTestHRP, addr[:])
33+
require.NoError(err)
34+
}
35+
args := BuildGenesisArgs{
36+
Encoding: formatting.Hex,
37+
GenesisData: map[string]AssetDefinition{
38+
"asset1": {
39+
Name: "myFixedCapAsset",
40+
Symbol: "MFCA",
41+
Denomination: 8,
42+
InitialState: map[string][]interface{}{
43+
"fixedCap": {
44+
Holder{
45+
Amount: 100000,
46+
Address: addrMap["A9bTQjfYGBFK3JPRJqF2eh3JYL7cHocvy"],
47+
},
48+
Holder{
49+
Amount: 100000,
50+
Address: addrMap["6mxBGnjGDCKgkVe7yfrmvMA7xE7qCv3vv"],
51+
},
52+
Holder{
53+
Amount: json.Uint64(startBalance),
54+
Address: addrMap["6ncQ19Q2U4MamkCYzshhD8XFjfwAWFzTa"],
55+
},
56+
Holder{
57+
Amount: json.Uint64(startBalance),
58+
Address: addrMap["Jz9ayEDt7dx9hDx45aXALujWmL9ZUuqe7"],
59+
},
60+
},
61+
},
62+
},
63+
"asset2": {
64+
Name: "myVarCapAsset",
65+
Symbol: "MVCA",
66+
InitialState: map[string][]interface{}{
67+
"variableCap": {
68+
Owners{
69+
Threshold: 1,
70+
Minters: []string{
71+
addrMap["A9bTQjfYGBFK3JPRJqF2eh3JYL7cHocvy"],
72+
addrMap["6mxBGnjGDCKgkVe7yfrmvMA7xE7qCv3vv"],
73+
},
74+
},
75+
Owners{
76+
Threshold: 2,
77+
Minters: []string{
78+
addrMap["6ncQ19Q2U4MamkCYzshhD8XFjfwAWFzTa"],
79+
addrMap["Jz9ayEDt7dx9hDx45aXALujWmL9ZUuqe7"],
80+
},
81+
},
82+
},
83+
},
84+
},
85+
"asset3": {
86+
Name: "myOtherVarCapAsset",
87+
InitialState: map[string][]interface{}{
88+
"variableCap": {
89+
Owners{
90+
Threshold: 1,
91+
Minters: []string{
92+
addrMap["A9bTQjfYGBFK3JPRJqF2eh3JYL7cHocvy"],
93+
},
94+
},
95+
},
96+
},
97+
},
98+
},
99+
}
100+
reply := BuildGenesisReply{}
101+
require.NoError(BuildGenesis(&args, &reply))
102+
}

vms/avm/service.md

-158
Original file line numberDiff line numberDiff line change
@@ -17,164 +17,6 @@ blockchain running the AVM.
1717

1818
## Methods
1919

20-
### `avm.buildGenesis`
21-
22-
Given a JSON representation of this Virtual Machine’s genesis state, create the byte representation
23-
of that state.
24-
25-
#### **Endpoint**
26-
27-
This call is made to the AVM’s static API endpoint:
28-
29-
`/ext/vm/avm`
30-
31-
Note: addresses should not include a chain prefix (that is `X-`) in calls to the static API endpoint
32-
because these prefixes refer to a specific chain.
33-
34-
**Signature:**
35-
36-
```sh
37-
avm.buildGenesis({
38-
networkID: int,
39-
genesisData: JSON,
40-
encoding: string, //optional
41-
}) -> {
42-
bytes: string,
43-
encoding: string,
44-
}
45-
```
46-
47-
Encoding specifies the encoding format to use for arbitrary bytes, that is the genesis bytes that are
48-
returned. Can only be `hex` when a value is provided.
49-
50-
`genesisData` has this form:
51-
52-
```json
53-
{
54-
"genesisData" :
55-
{
56-
"assetAlias1": { // Each object defines an asset
57-
"name": "human readable name",
58-
"symbol":"AVAL", // Symbol is between 0 and 4 characters
59-
"initialState": {
60-
"fixedCap" : [ // Choose the asset type.
61-
{ // Can be "fixedCap", "variableCap", "limitedTransfer", "nonFungible"
62-
"amount":1000, // At genesis, address A has
63-
"address":"A" // 1000 units of asset
64-
},
65-
{
66-
"amount":5000, // At genesis, address B has
67-
"address":"B" // 1000 units of asset
68-
},
69-
... // Can have many initial holders
70-
]
71-
}
72-
},
73-
"assetAliasCanBeAnythingUnique": { // Asset alias can be used in place of assetID in calls
74-
"name": "human readable name", // names need not be unique
75-
"symbol": "AVAL", // symbols need not be unique
76-
"initialState": {
77-
"variableCap" : [ // No units of the asset exist at genesis
78-
{
79-
"minters": [ // The signature of A or B can mint more of
80-
"A", // the asset.
81-
"B"
82-
],
83-
"threshold":1
84-
},
85-
{
86-
"minters": [ // The signatures of 2 of A, B and C can mint
87-
"A", // more of the asset
88-
"B",
89-
"C"
90-
],
91-
"threshold":2
92-
},
93-
... // Can have many minter sets
94-
]
95-
}
96-
},
97-
... // Can list more assets
98-
}
99-
}
100-
```
101-
102-
**Example Call:**
103-
104-
```sh
105-
curl -X POST --data '{
106-
"jsonrpc": "2.0",
107-
"id" : 1,
108-
"method" : "avm.buildGenesis",
109-
"params" : {
110-
"networkId": 16,
111-
"genesisData": {
112-
"asset1": {
113-
"name": "myFixedCapAsset",
114-
"symbol":"MFCA",
115-
"initialState": {
116-
"fixedCap" : [
117-
{
118-
"amount":100000,
119-
"address": "avax13ery2kvdrkd2nkquvs892gl8hg7mq4a6ufnrn6"
120-
},
121-
{
122-
"amount":100000,
123-
"address": "avax1rvks3vpe4cm9yc0rrk8d5855nd6yxxutfc2h2r"
124-
},
125-
{
126-
"amount":50000,
127-
"address": "avax1ntj922dj4crc4pre4e0xt3dyj0t5rsw9uw0tus"
128-
},
129-
{
130-
"amount":50000,
131-
"address": "avax1yk0xzmqyyaxn26sqceuky2tc2fh2q327vcwvda"
132-
}
133-
]
134-
}
135-
},
136-
"asset2": {
137-
"name": "myVarCapAsset",
138-
"symbol":"MVCA",
139-
"initialState": {
140-
"variableCap" : [
141-
{
142-
"minters": [
143-
"avax1kcfg6avc94ct3qh2mtdg47thsk8nrflnrgwjqr",
144-
"avax14e2s22wxvf3c7309txxpqs0qe9tjwwtk0dme8e"
145-
],
146-
"threshold":1
147-
},
148-
{
149-
"minters": [
150-
"avax1y8pveyn82gjyqr7kqzp72pqym6xlch9gt5grck",
151-
"avax1c5cmm0gem70rd8dcnpel63apzfnfxye9kd4wwe",
152-
"avax12euam2lwtwa8apvfdl700ckhg86euag2hlhmyw"
153-
],
154-
"threshold":2
155-
}
156-
]
157-
}
158-
}
159-
},
160-
"encoding": "hex"
161-
}
162-
}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/vm/avm
163-
```
164-
165-
**Example Response:**
166-
167-
```json
168-
{
169-
"jsonrpc": "2.0",
170-
"result": {
171-
"bytes": "0x0000000000010006617373657431000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f6d794669786564436170417373657400044d464341000000000100000000000000010000000700000000000186a10000000000000000000000010000000152b219bc1b9ab0a9f2e3f9216e4460bd5db8d153bfa57c3c",
172-
"encoding": "hex"
173-
},
174-
"id": 1
175-
}
176-
```
177-
17820
### `avm.getAllBalances`
17921

18022
<Callout type="warn">

vms/platformvm/api/static_service.go renamed to vms/platformvm/api/genesis_builder.go

+1-5
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"cmp"
88
"errors"
99
"fmt"
10-
"net/http"
1110

1211
"github.com/ava-labs/avalanchego/ids"
1312
"github.com/ava-labs/avalanchego/utils"
@@ -39,9 +38,6 @@ var (
3938
_ utils.Sortable[UTXO] = UTXO{}
4039
)
4140

42-
// StaticService defines the static API methods exposed by the platform VM
43-
type StaticService struct{}
44-
4541
// UTXO is a UTXO on the Platform Chain that exists at the chain's genesis.
4642
type UTXO struct {
4743
Locktime json.Uint64 `json:"locktime"`
@@ -194,7 +190,7 @@ func bech32ToID(addrStr string) (ids.ShortID, error) {
194190
}
195191

196192
// BuildGenesis build the genesis state of the Platform Chain (and thereby the Avalanche network.)
197-
func (*StaticService) BuildGenesis(_ *http.Request, args *BuildGenesisArgs, reply *BuildGenesisReply) error {
193+
func BuildGenesis(args *BuildGenesisArgs, reply *BuildGenesisReply) error {
198194
// Specify the UTXOs on the Platform chain that exist at genesis.
199195
utxos := make([]*genesis.UTXO, 0, len(args.UTXOs))
200196
for i, apiUTXO := range args.UTXOs {

vms/platformvm/api/static_service_test.go renamed to vms/platformvm/api/genesis_builder_test.go

+4-8
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,7 @@ func TestBuildGenesisInvalidUTXOBalance(t *testing.T) {
5555
}
5656
reply := BuildGenesisReply{}
5757

58-
ss := StaticService{}
59-
err = ss.BuildGenesis(nil, &args, &reply)
58+
err = BuildGenesis(&args, &reply)
6059
require.ErrorIs(err, errUTXOHasNoValue)
6160
}
6261

@@ -99,8 +98,7 @@ func TestBuildGenesisInvalidStakeWeight(t *testing.T) {
9998
}
10099
reply := BuildGenesisReply{}
101100

102-
ss := StaticService{}
103-
err = ss.BuildGenesis(nil, &args, &reply)
101+
err = BuildGenesis(&args, &reply)
104102
require.ErrorIs(err, errValidatorHasNoWeight)
105103
}
106104

@@ -144,8 +142,7 @@ func TestBuildGenesisInvalidEndtime(t *testing.T) {
144142
}
145143
reply := BuildGenesisReply{}
146144

147-
ss := StaticService{}
148-
err = ss.BuildGenesis(nil, &args, &reply)
145+
err = BuildGenesis(&args, &reply)
149146
require.ErrorIs(err, errValidatorAlreadyExited)
150147
}
151148

@@ -224,8 +221,7 @@ func TestBuildGenesisReturnsSortedValidators(t *testing.T) {
224221
}
225222
reply := BuildGenesisReply{}
226223

227-
ss := StaticService{}
228-
require.NoError(ss.BuildGenesis(nil, &args, &reply))
224+
require.NoError(BuildGenesis(&args, &reply))
229225

230226
genesisBytes, err := formatting.Decode(reply.Encoding, reply.Bytes)
231227
require.NoError(err)

0 commit comments

Comments
 (0)