Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arcadia rollup #28

Merged
merged 4 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions actions/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ var (
ErrNameSpaceNotRegistered = errors.New("namespace not registered")
ErrNotAuthorized = errors.New("not authorized")
ErrNameSpaceAlreadyRegistered = errors.New("namespace already registered")
ErrExitEpochSmallerThanStartEpoch = errors.New("exit epoch is smaller than start epoch")
)
45 changes: 23 additions & 22 deletions actions/rollup_register.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"context"
"encoding/hex"
"fmt"
"slices"

hactions "github.com/AnomalyFi/hypersdk/actions"
"github.com/AnomalyFi/hypersdk/chain"
Expand All @@ -20,7 +19,7 @@ var _ chain.Action = (*RollupRegistration)(nil)

const (
CreateRollup = iota
DeleteRollup
ExitRollup
UpdateRollup
)

Expand All @@ -45,6 +44,8 @@ func (*RollupRegistration) StateKeysMaxChunks() []uint16 {
return []uint16{hactions.RollupInfoChunks, hactions.RollupRegistryChunks}
}

// TODO: this action needs to be managed by DAO to manage deletions since we are not deleting any namespace from storage
// but only by marking them as regsitered or exited
func (r *RollupRegistration) Execute(
ctx context.Context,
rules chain.Rules,
Expand All @@ -69,17 +70,18 @@ func (r *RollupRegistration) Execute(

switch r.OpCode {
case CreateRollup:
if r.Info.StartEpoch < Epoch(hght, rules.GetEpochLength())+2 {
return nil, fmt.Errorf("epoch number is not valid, minimum: %d, actual: %d", Epoch(hght, rules.GetEpochLength())+2, r.Info.StartEpoch)
}
if contains(namespaces, r.Namespace) {
return nil, ErrNameSpaceAlreadyRegistered
}
if r.Info.StartEpoch < Epoch(hght, rules.GetEpochLength())+2 || r.Info.ExitEpoch != 0 {
return nil, fmt.Errorf("epoch number is not valid, minimum: %d, actual: %d, exit: %d", Epoch(hght, rules.GetEpochLength())+2, r.Info.StartEpoch, r.Info.ExitEpoch)
}
namespaces = append(namespaces, r.Namespace)
if err := storage.SetRollupInfo(ctx, mu, r.Namespace, &r.Info); err != nil {
return nil, fmt.Errorf("unable to set rollup info(CREATE): %s", err.Error())
}
case UpdateRollup:
// only allow modifing informations that are not related to ExitEpoch or StartEpoch
if err := authorizationChecks(ctx, actor, namespaces, r.Namespace, mu); err != nil {
return nil, fmt.Errorf("authorization failed(UPDATE): %s", err.Error())
}
Expand All @@ -88,32 +90,31 @@ func (r *RollupRegistration) Execute(
if err != nil {
return nil, fmt.Errorf("unable to get existing rollup info(UPDATE): %s", err.Error())
}
if r.Info.StartEpoch != rollupInfoExists.StartEpoch && r.Info.StartEpoch < Epoch(hght, rules.GetEpochLength())+2 {
return nil, fmt.Errorf("(UPDATE)epoch number is not valid, minimum: %d, actual: %d, prev: %d", Epoch(hght, rules.GetEpochLength())+2, r.Info.StartEpoch, rollupInfoExists.StartEpoch)
}

// rewrite epoch info
r.Info.ExitEpoch = rollupInfoExists.ExitEpoch
r.Info.StartEpoch = rollupInfoExists.StartEpoch

if err := storage.SetRollupInfo(ctx, mu, r.Namespace, &r.Info); err != nil {
return nil, fmt.Errorf("unable to set rollup info(UPDATE): %s", err.Error())
}
case DeleteRollup:
case ExitRollup:
if err := authorizationChecks(ctx, actor, namespaces, r.Namespace, mu); err != nil {
return nil, fmt.Errorf("unable to set rollup info(DELETE): %s", err.Error())
return nil, fmt.Errorf("unable to set rollup info(EXIT): %s", err.Error())
}
rollupInfoExists, err := storage.GetRollupInfo(ctx, mu, r.Namespace)
if err != nil {
return nil, fmt.Errorf("unable to get existing rollup info(UPDATE): %s", err.Error())
}
if r.Info.StartEpoch < Epoch(hght, rules.GetEpochLength())+2 {
return nil, fmt.Errorf("(DELETE)epoch number is not valid, minimum: %d, actual: %d", Epoch(hght, rules.GetEpochLength())+2, r.Info.StartEpoch)
if r.Info.ExitEpoch < rollupInfoExists.StartEpoch || r.Info.ExitEpoch < Epoch(hght, rules.GetEpochLength())+2 {
return nil, fmt.Errorf("(EXIT)epoch number is not valid, minimum: %d, actual: %d, start: %d", Epoch(hght, rules.GetEpochLength())+2, r.Info.ExitEpoch, rollupInfoExists.StartEpoch)
}

nsIdx := -1
for i, ns := range namespaces {
if bytes.Equal(r.Namespace, ns) {
nsIdx = i
break
}
}
namespaces = slices.Delete(namespaces, nsIdx, nsIdx+1)
// overwrite StartEpoch
r.Info.StartEpoch = rollupInfoExists.StartEpoch

if err := storage.DelRollupInfo(ctx, mu, r.Namespace); err != nil {
return nil, err
if err := storage.SetRollupInfo(ctx, mu, r.Namespace, &r.Info); err != nil {
return nil, fmt.Errorf("unable to set rollup info(EXIT): %s", err.Error())
}
default:
return nil, fmt.Errorf("op code(%d) not supported", r.OpCode)
Expand Down
6 changes: 4 additions & 2 deletions cmd/seq-cli/cmd/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ var rollupCmd = &cobra.Command{
return err
}

op, err := handler.Root().PromptChoice("(0)create (1)delete (2)update", 3)
op, err := handler.Root().PromptChoice("(0)create (1)exit (2)update", 3)
if err != nil {
return err
}
Expand All @@ -133,7 +133,9 @@ var rollupCmd = &cobra.Command{
FeeRecipient: feeRecipient,
Namespace: namespace,
AuthoritySEQAddress: feeRecipient,
StartEpoch: e + 4,
SequencerPublicKey: feeRecipient[:],
StartEpoch: e + 10,
ExitEpoch: 0,
}
// Generate transaction
_, err = sendAndWait(ctx, []chain.Action{&actions.RollupRegistration{
Expand Down
16 changes: 14 additions & 2 deletions controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@
"fmt"
"net/http"

hactions "github.com/AnomalyFi/hypersdk/actions"

Check failure on line 11 in controller/controller.go

View workflow job for this annotation

GitHub Actions / seq-e2e-tests

github.com/AnomalyFi/[email protected]: replacement directory ../hypersdk does not exist

Check failure on line 11 in controller/controller.go

View workflow job for this annotation

GitHub Actions / seq-e2e-tests

github.com/AnomalyFi/[email protected]: replacement directory ../hypersdk does not exist

Check failure on line 11 in controller/controller.go

View workflow job for this annotation

GitHub Actions / seq-e2e-tests

github.com/AnomalyFi/[email protected]: replacement directory ../hypersdk does not exist

"github.com/AnomalyFi/hypersdk/builder"

Check failure on line 13 in controller/controller.go

View workflow job for this annotation

GitHub Actions / seq-e2e-tests

github.com/AnomalyFi/[email protected]: replacement directory ../hypersdk does not exist

Check failure on line 13 in controller/controller.go

View workflow job for this annotation

GitHub Actions / seq-e2e-tests

github.com/AnomalyFi/[email protected]: replacement directory ../hypersdk does not exist

Check failure on line 13 in controller/controller.go

View workflow job for this annotation

GitHub Actions / seq-e2e-tests

github.com/AnomalyFi/[email protected]: replacement directory ../hypersdk does not exist
"github.com/AnomalyFi/hypersdk/chain"
"github.com/AnomalyFi/hypersdk/fees"

Check failure on line 15 in controller/controller.go

View workflow job for this annotation

GitHub Actions / seq-e2e-tests

github.com/AnomalyFi/[email protected]: replacement directory ../hypersdk does not exist

Check failure on line 15 in controller/controller.go

View workflow job for this annotation

GitHub Actions / seq-e2e-tests

github.com/AnomalyFi/[email protected]: replacement directory ../hypersdk does not exist

Check failure on line 15 in controller/controller.go

View workflow job for this annotation

GitHub Actions / seq-e2e-tests

github.com/AnomalyFi/[email protected]: replacement directory ../hypersdk does not exist
"github.com/AnomalyFi/hypersdk/gossiper"

Check failure on line 16 in controller/controller.go

View workflow job for this annotation

GitHub Actions / seq-e2e-tests

github.com/AnomalyFi/[email protected]: replacement directory ../hypersdk does not exist

Check failure on line 16 in controller/controller.go

View workflow job for this annotation

GitHub Actions / seq-e2e-tests

github.com/AnomalyFi/[email protected]: replacement directory ../hypersdk does not exist

Check failure on line 16 in controller/controller.go

View workflow job for this annotation

GitHub Actions / seq-e2e-tests

github.com/AnomalyFi/[email protected]: replacement directory ../hypersdk does not exist
hrpc "github.com/AnomalyFi/hypersdk/rpc"

Check failure on line 17 in controller/controller.go

View workflow job for this annotation

GitHub Actions / seq-e2e-tests

github.com/AnomalyFi/[email protected]: replacement directory ../hypersdk does not exist

Check failure on line 17 in controller/controller.go

View workflow job for this annotation

GitHub Actions / seq-e2e-tests

github.com/AnomalyFi/[email protected]: replacement directory ../hypersdk does not exist

Check failure on line 17 in controller/controller.go

View workflow job for this annotation

GitHub Actions / seq-e2e-tests

github.com/AnomalyFi/[email protected]: replacement directory ../hypersdk does not exist
hstorage "github.com/AnomalyFi/hypersdk/storage"

Check failure on line 18 in controller/controller.go

View workflow job for this annotation

GitHub Actions / seq-e2e-tests

github.com/AnomalyFi/[email protected]: replacement directory ../hypersdk does not exist

Check failure on line 18 in controller/controller.go

View workflow job for this annotation

GitHub Actions / seq-e2e-tests

github.com/AnomalyFi/[email protected]: replacement directory ../hypersdk does not exist

Check failure on line 18 in controller/controller.go

View workflow job for this annotation

GitHub Actions / seq-e2e-tests

github.com/AnomalyFi/[email protected]: replacement directory ../hypersdk does not exist
"github.com/AnomalyFi/hypersdk/vm"

Check failure on line 19 in controller/controller.go

View workflow job for this annotation

GitHub Actions / seq-e2e-tests

github.com/AnomalyFi/[email protected]: replacement directory ../hypersdk does not exist

Check failure on line 19 in controller/controller.go

View workflow job for this annotation

GitHub Actions / seq-e2e-tests

github.com/AnomalyFi/[email protected]: replacement directory ../hypersdk does not exist

Check failure on line 19 in controller/controller.go

View workflow job for this annotation

GitHub Actions / seq-e2e-tests

github.com/AnomalyFi/[email protected]: replacement directory ../hypersdk does not exist
ametrics "github.com/ava-labs/avalanchego/api/metrics"
"github.com/ava-labs/avalanchego/database"
"github.com/ava-labs/avalanchego/snow"
Expand All @@ -26,6 +28,7 @@
"github.com/AnomalyFi/nodekit-seq/config"
"github.com/AnomalyFi/nodekit-seq/consts"
"github.com/AnomalyFi/nodekit-seq/genesis"
rollupregistry "github.com/AnomalyFi/nodekit-seq/rollup_registry"
"github.com/AnomalyFi/nodekit-seq/rpc"
"github.com/AnomalyFi/nodekit-seq/storage"
"github.com/AnomalyFi/nodekit-seq/version"
Expand All @@ -41,8 +44,9 @@
config *config.Config
stateManager *StateManager

jsonRPCServer *rpc.JSONRPCServer
archiver *archiver.ORMArchiver
jsonRPCServer *rpc.JSONRPCServer
archiver *archiver.ORMArchiver
rollupRegistry *rollupregistry.RollupRegistry

metrics *metrics

Expand Down Expand Up @@ -134,6 +138,8 @@
return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err
}

c.rollupRegistry = rollupregistry.NewRollupRegistr()

apis[rpc.JSONRPCEndpoint] = jsonRPCHandler

// Create builder and gossiper
Expand Down Expand Up @@ -199,6 +205,7 @@
}
}()

rollups := make([]*hactions.RollupInfo, 0)
results := blk.Results()
for i, tx := range blk.Txs {
result := results[i]
Expand All @@ -223,10 +230,15 @@
c.metrics.transfer.Inc()
case *actions.SequencerMsg:
c.metrics.sequencerMsg.Inc()
case *actions.RollupRegistration:
reg := act.(*actions.RollupRegistration)
rollups = append(rollups, &reg.Info)
}
}
}
}
currentEpoch := blk.Hght / uint64(c.inner.Rules(blk.Tmstmp).GetEpochLength())
c.rollupRegistry.Update(currentEpoch, rollups)
return batch.Write()
}

Expand Down
5 changes: 5 additions & 0 deletions controller/resolutions.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/AnomalyFi/nodekit-seq/archiver"
"github.com/AnomalyFi/nodekit-seq/genesis"
rollupregistry "github.com/AnomalyFi/nodekit-seq/rollup_registry"
"github.com/AnomalyFi/nodekit-seq/storage"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/trace"
Expand Down Expand Up @@ -83,6 +84,10 @@ func (c *Controller) Archiver() *archiver.ORMArchiver {
return c.archiver
}

func (c *Controller) RollupRegistry() *rollupregistry.RollupRegistry {
return c.rollupRegistry
}

func (c *Controller) NetworkID() uint32 {
return c.snowCtx.NetworkID
}
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/AnomalyFi/nodekit-seq
go 1.21.12

require (
github.com/AnomalyFi/hypersdk v0.9.7-arcadia.12
github.com/AnomalyFi/hypersdk v0.9.7-arcadia.13
github.com/ava-labs/avalanche-network-runner v1.7.4-rc.0
github.com/ava-labs/avalanchego v1.11.10
github.com/ethereum/go-ethereum v1.13.14
Expand Down Expand Up @@ -173,4 +173,4 @@ require (

// replace github.com/ava-labs/coreth => github.com/AnomalyFi/coreth v0.12.5-rc.6.1

// replace github.com/AnomalyFi/hypersdk => ../hypersdk
replace github.com/AnomalyFi/hypersdk => ../hypersdk
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7
filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek=
filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/AnomalyFi/hypersdk v0.9.7-arcadia.12 h1:X5m2I249t4OMkCa2hAtB0VkDMcSFLtvl0QDBa3GR+AA=
github.com/AnomalyFi/hypersdk v0.9.7-arcadia.12/go.mod h1:0Vj2PdwSFN7pat4Sno39IfmtOiv/gO9mxZXyRKnoKtI=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
Expand Down
60 changes: 60 additions & 0 deletions rollup_registry/registry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package rollupregistry

import (
"maps"
"sync"

hactions "github.com/AnomalyFi/hypersdk/actions"
"github.com/ava-labs/avalanchego/ids"
)

type RollupRegistryOnlyRead interface {
RollupsValidAtEpoch(epoch uint64) []*hactions.RollupInfo
}

type RollupRegistryAllPerm interface {
RollupRegistryOnlyRead
Update(currentEpoch uint64, rollups []*hactions.RollupInfo)
}

var _ RollupRegistryAllPerm = (*RollupRegistry)(nil)

type RollupRegistry struct {
rollups map[ids.ID]*hactions.RollupInfo
rollupsL sync.RWMutex
}

func NewRollupRegistr() *RollupRegistry {
return &RollupRegistry{
rollups: make(map[ids.ID]*hactions.RollupInfo),
}
}

func (r *RollupRegistry) RollupsValidAtEpoch(epoch uint64) []*hactions.RollupInfo {
r.rollupsL.RLock()
defer r.rollupsL.RUnlock()

ret := make([]*hactions.RollupInfo, 0)
for _, rollup := range r.rollups {
if !rollup.ValidAtEpoch(epoch) {
continue
}

ret = append(ret, rollup)
}

return ret
}

func (r *RollupRegistry) Update(currentEpoch uint64, rollups []*hactions.RollupInfo) {
r.rollupsL.Lock()
defer r.rollupsL.Unlock()

for _, rollup := range rollups {
r.rollups[rollup.ID()] = rollup
}

maps.DeleteFunc(r.rollups, func(_ ids.ID, rollup *hactions.RollupInfo) bool {
return rollup.Exited(currentEpoch)
})
}
2 changes: 2 additions & 0 deletions rpc/dependencies.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/AnomalyFi/hypersdk/fees"
"github.com/AnomalyFi/nodekit-seq/archiver"
"github.com/AnomalyFi/nodekit-seq/genesis"
rollupregistry "github.com/AnomalyFi/nodekit-seq/rollup_registry"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/trace"
"github.com/ava-labs/avalanchego/utils/logging"
Expand Down Expand Up @@ -39,4 +40,5 @@ type Controller interface {
Logger() logging.Logger
// TODO: update this to only have read permission
Archiver() *archiver.ORMArchiver
RollupRegistry() *rollupregistry.RollupRegistry
}
11 changes: 11 additions & 0 deletions rpc/jsonrpc_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,17 @@ func (cli *JSONRPCClient) GetAllRollupInfo(ctx context.Context) (*types.GetAllRo
return resp, err
}

func (cli *JSONRPCClient) GetValidRollupsAtEpoch(ctx context.Context, epoch uint64) (*types.GetRollupsInfoAtEpochReply, error) {
resp := new(types.GetRollupsInfoAtEpochReply)
err := cli.requester.SendRequest(
ctx,
"getValidRollupsAtEpoch",
types.GetRollupsInfoAtEpochArgs{Epoch: epoch},
resp,
)
return resp, err
}

func (cli *JSONRPCClient) GetEpochExits(ctx context.Context, epoch uint64) (*hactions.EpochExitInfo, error) {
resp := new(types.EpochExitsReply)
args := &types.EpochExitsArgs{Epoch: epoch}
Expand Down
6 changes: 6 additions & 0 deletions rpc/jsonrpc_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,12 @@ func (j *JSONRPCServer) GetAllRollupInfo(req *http.Request, _ *struct{}, reply *
return nil
}

func (j *JSONRPCServer) GetValidRollupsAtEpoch(req *http.Request, args *types.GetRollupsInfoAtEpochArgs, reply *types.GetRollupsInfoAtEpochReply) error {
registry := j.c.RollupRegistry()
reply.Rollups = registry.RollupsValidAtEpoch(args.Epoch)
return nil
}

var _ chain.Parser = (*ServerParser)(nil)

type ServerParser struct {
Expand Down
6 changes: 5 additions & 1 deletion scripts/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,13 @@ find "${TMPDIR}"/avalanchego-"${VERSION}"
# Make sure to replace this address with your own address
# if you are starting your own devnet (otherwise anyone can access
# funds using the included demo.pk)
# total stake can allocate: 10000000000000000000, make sure it is below this or genesis won't load
echo "creating allocations file"
cat <<EOF > "${TMPDIR}"/allocations.json
[{"address":"${ADDRESS}", "balance":10000000000000000000}]
[
{"address":"${ADDRESS}", "balance":1000000000000000000},
{"address":"seq1qy94dndd0wzru9gvq3ayw52ngcd2fuhyptt58f4a3eppjzpx573qg9cr7sm", "balance":1000000000000000000}
]
EOF

GENESIS_PATH=$2
Expand Down
Loading
Loading