Skip to content

Commit

Permalink
Merge pull request #28 from AnomalyFi/arcadia-rollup
Browse files Browse the repository at this point in the history
Arcadia rollup
  • Loading branch information
bianyuanop authored Dec 19, 2024
2 parents 4901100 + a7ba8af commit 092bcbc
Show file tree
Hide file tree
Showing 14 changed files with 270 additions and 33 deletions.
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,6 +8,8 @@ import (
"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

"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
"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
Expand All @@ -26,6 +28,7 @@ import (
"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 @@ type Controller struct {
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 @@ func (c *Controller) Initialize(
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 @@ func (c *Controller) Accepted(ctx context.Context, blk *chain.StatelessBlock) er
}
}()

rollups := make([]*hactions.RollupInfo, 0)
results := blk.Results()
for i, tx := range blk.Txs {
result := results[i]
Expand All @@ -223,10 +230,15 @@ func (c *Controller) Accepted(ctx context.Context, blk *chain.StatelessBlock) er
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

0 comments on commit 092bcbc

Please sign in to comment.