Skip to content

Commit

Permalink
Merge pull request #25 from AnomalyFi/arcadia
Browse files Browse the repository at this point in the history
SEQ Upgrades for Arcadia
  • Loading branch information
mtgnoah authored Nov 1, 2024
2 parents 0feb66b + 77aeb0f commit 38d7ba5
Show file tree
Hide file tree
Showing 36 changed files with 1,787 additions and 834 deletions.
140 changes: 0 additions & 140 deletions actions/anchor_register.go

This file was deleted.

165 changes: 165 additions & 0 deletions actions/auction.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
package actions

import (
"context"
"encoding/binary"
"fmt"

"github.com/AnomalyFi/hypersdk/chain"
"github.com/AnomalyFi/hypersdk/codec"
"github.com/AnomalyFi/hypersdk/consts"
"github.com/AnomalyFi/hypersdk/crypto/bls"
"github.com/AnomalyFi/hypersdk/state"
"github.com/AnomalyFi/hypersdk/utils"
"github.com/AnomalyFi/nodekit-seq/auth"
"github.com/AnomalyFi/nodekit-seq/storage"
"github.com/ava-labs/avalanchego/ids"
)

var _ chain.Action = (*Auction)(nil)

type AuctionInfo struct {
EpochNumber uint64 `json:"epochNumber"`
BidPrice uint64 `json:"bidPrice"`
BuilderSEQAddress codec.Address `json:"builderSEQAddress"`
}

func (info *AuctionInfo) Marshal(p *codec.Packer) {
p.PackUint64(info.EpochNumber)
p.PackUint64(info.BidPrice)
p.PackAddress(info.BuilderSEQAddress)
}

func UnmarshalAuctionInfo(p *codec.Packer) (*AuctionInfo, error) {
var auctionInfo AuctionInfo
auctionInfo.EpochNumber = p.UnpackUint64(true)
auctionInfo.BidPrice = p.UnpackUint64(true)
p.UnpackAddress(&auctionInfo.BuilderSEQAddress)
if p.Err() != nil {
return nil, p.Err()
}
return &auctionInfo, nil
}

type Auction struct {
AuctionInfo AuctionInfo `json:"auctionInfo"`
BuilderPublicKey []byte `json:"builderPublicKey"` // BLS public key of the bidder.
BuilderSignature []byte `json:"signature"`
}

func (*Auction) GetTypeID() uint8 {
return AuctionID
}

func (a *Auction) StateKeys(actor codec.Address, _ ids.ID) state.Keys {
return state.Keys{
string(storage.BalanceKey(a.AuctionInfo.BuilderSEQAddress)): state.Read | state.Write,
string(storage.BalanceKey(ArcadiaFundAddress())): state.All,
string(storage.ArcadiaBidKey(a.AuctionInfo.EpochNumber)): state.Write | state.Allocate,
}
}

func (*Auction) StateKeysMaxChunks() []uint16 {
return []uint16{storage.BalanceChunks, storage.BalanceChunks, storage.EpochExitsChunks}
}

// This is a permissioned action, only authorized address can pass the execution.
func (a *Auction) Execute(
ctx context.Context,
rules chain.Rules,
mu state.Mutable,
_ int64,
hght uint64,
actor codec.Address,
_ ids.ID,
) ([][]byte, error) {
// TODO: this allows any whitelisted address to submit arcadia bid.
// change this to only allow the arcadia address to submit the bid.
if !isWhiteListed(rules, actor) {
return nil, ErrNotWhiteListed
}

// Allow auction bid for next epoch processed only during the current epoch.
if a.AuctionInfo.EpochNumber != Epoch(hght, rules.GetEpochLength())+1 {
return nil, fmt.Errorf("epoch number is not valid, expected: %d, actual: %d", Epoch(hght, rules.GetEpochLength())+1, a.AuctionInfo.EpochNumber)
}

pubkey, err := bls.PublicKeyFromBytes(a.BuilderPublicKey)
if err != nil {
return nil, fmt.Errorf("failed to parse public key: %w", err)
}

msg := make([]byte, 16)
binary.BigEndian.PutUint64(msg[:8], a.AuctionInfo.EpochNumber)
binary.BigEndian.PutUint64(msg[8:], a.AuctionInfo.BidPrice)
msg = append(msg, a.BuilderPublicKey...)
sig, err := bls.SignatureFromBytes(a.BuilderSignature)
if err != nil {
return nil, fmt.Errorf("failed to parse signature: %w", err)
}

// Verify the signature.
if !bls.Verify(msg, pubkey, sig) {
return nil, ErrInvalidBidderSignature
}

builderSEQAddress := codec.CreateAddress(auth.BLSID, utils.ToID(a.BuilderPublicKey))
if builderSEQAddress != a.AuctionInfo.BuilderSEQAddress {
return nil, ErrParsedBuilderSEQAddressMismatch
}
// deduct the bid amount from bidder.
if err := storage.SubBalance(ctx, mu, builderSEQAddress, a.AuctionInfo.BidPrice); err != nil {
return nil, err
}

// Bid amount is sent to the Arcadia fund address.
if err := storage.AddBalance(ctx, mu, ArcadiaFundAddress(), a.AuctionInfo.BidPrice, true); err != nil {
return nil, err
}

// Store bid information.
if err := storage.StoreArcadiaBidInfo(ctx, mu, a.AuctionInfo.EpochNumber, a.AuctionInfo.BidPrice, a.BuilderPublicKey, a.BuilderSignature); err != nil {
return nil, err
}

return nil, nil
}

func (*Auction) ComputeUnits(codec.Address, chain.Rules) uint64 {
return AuctionComputeUnits
}

func (a *Auction) Size() int {
return 2*consts.Uint64Len + bls.PublicKeyLen + bls.SignatureLen + codec.AddressLen
}

func (a *Auction) Marshal(p *codec.Packer) {
a.AuctionInfo.Marshal(p)
p.PackBytes(a.BuilderPublicKey)
p.PackBytes(a.BuilderSignature)
}

func UnmarshalAuction(p *codec.Packer) (chain.Action, error) {
var auction Auction
auctionInfo, err := UnmarshalAuctionInfo(p)
if err != nil {
return nil, err
}
auction.AuctionInfo = *auctionInfo
p.UnpackBytes(48, true, &auction.BuilderPublicKey)
p.UnpackBytes(96, true, &auction.BuilderSignature)
return &auction, p.Err()
}

func (*Auction) ValidRange(chain.Rules) (int64, int64) {
// Returning -1, -1 means that the action is always valid.
return -1, -1
}

func (*Auction) NMTNamespace() []byte {
return DefaultNMTNamespace
}

func (*Auction) UseFeeMarket() bool {
return false
}
4 changes: 3 additions & 1 deletion actions/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ const (
TransferID uint8 = 0
MsgID uint8 = 1
ExitID uint8 = 2
AuctionID uint8 = 3
)

const (
// TODO: tune this
TransferComputeUnits = 1
EpochExitComputeUnits = 1
EpochExitComputeUnits = 10
AuctionComputeUnits = 4

MsgComputeUnits = 15

Expand Down
Loading

0 comments on commit 38d7ba5

Please sign in to comment.