Skip to content

Commit

Permalink
add newseed api
Browse files Browse the repository at this point in the history
  • Loading branch information
cmcater committed Aug 1, 2023
1 parent 4f8ae3b commit 328f23e
Show file tree
Hide file tree
Showing 8 changed files with 1,333 additions and 621 deletions.
96 changes: 0 additions & 96 deletions internal/pkg/chainsdk/core/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"fmt"

"github.com/golang/protobuf/proto"
"github.com/google/uuid"
"github.com/rumsystem/quorum/internal/pkg/conn"
"github.com/rumsystem/quorum/internal/pkg/logging"
"github.com/rumsystem/quorum/internal/pkg/nodectx"
Expand All @@ -17,108 +16,13 @@ import (

var group_log = logging.Logger("group")

const DEFAULT_EPOCH_DURATION = 1000 //ms
const INIT_FORK_TRX_ID = "00000000-0000-0000-0000-000000000000"

type Group struct {
Item *quorumpb.GroupItem
ChainCtx *Chain
GroupId string
Nodename string
}

func (grp *Group) NewGroup(item *quorumpb.GroupItem) (*quorumpb.Block, error) {
group_log.Debugf("<%s> NewGroup called", item.GroupId)

grp.Item = item
grp.GroupId = item.GroupId
grp.Nodename = nodectx.GetNodeCtx().Name

//create and initial chain
grp.ChainCtx = &Chain{}
grp.ChainCtx.NewChain(item, grp.Nodename, false)

ks := nodectx.GetNodeCtx().Keystore

//create initial consensus for genesis block
consensusInfo := &quorumpb.ConsensusInfo{
ConsensusId: uuid.New().String(),
ChainVer: 0,
InTrx: INIT_FORK_TRX_ID,
ForkFromBlock: 0,
}

//save consensus info to db
group_log.Debugf("<%s> save consensus result", grp.Item.GroupId)
err := nodectx.GetNodeCtx().GetChainStorage().SaveGroupConsensusInfo(item.GroupId, consensusInfo, grp.Nodename)
if err != nil {
group_log.Debugf("<%s> save consensus result failed", grp.Item.GroupId)
return nil, err
}

//create fork trx
forkItem := &quorumpb.ForkItem{
GroupId: item.GroupId,
Consensus: consensusInfo,
StartFromBlock: 0,
StartFromEpoch: 0,
EpochDuration: DEFAULT_EPOCH_DURATION,
Producers: []string{item.OwnerPubKey}, //owner is the first producer
Memo: "genesis fork",
}

forkTrx, err := grp.ChainCtx.GetTrxFactory().GetForkTrx("", forkItem)
if err != nil {
return nil, err
}

//create and save genesis block
group_log.Debugf("<%s> create and save genesis block", grp.Item.GroupId)
genesisBlock, err := rumchaindata.CreateGenesisBlockByEthKey(item.GroupId, consensusInfo, forkTrx, item.OwnerPubKey, ks, "")
err = nodectx.GetNodeCtx().GetChainStorage().AddGensisBlock(genesisBlock, false, grp.Nodename)
if err != nil {
return nil, err
}

//add group owner as the first group producer
group_log.Debugf("<%s> add owner as the first producer", grp.Item.GroupId)
pItem := &quorumpb.ProducerItem{}
pItem.GroupId = item.GroupId
pItem.ProducerPubkey = item.OwnerPubKey
pItem.ProofTrxId = ""
pItem.BlkCnt = 0
pItem.Memo = "Owner Registated as the first group producer"
err = nodectx.GetNodeCtx().GetChainStorage().AddProducer(pItem, grp.Nodename)
if err != nil {
return nil, err
}

//load and update group producers
grp.ChainCtx.updateProducerPool()

//create and register ConnMgr for chainctx
conn.GetConn().RegisterChainCtx(item.GroupId,
item.OwnerPubKey,
item.UserSignPubkey,
grp.ChainCtx)

//commented by cuicat
//update producer list for ConnMgr just created
//grp.ChainCtx.UpdConnMgrProducer()

//create group consensus
grp.ChainCtx.CreateConsensus()

//save groupItem to db
err = nodectx.GetNodeCtx().GetChainStorage().AddGroup(grp.Item)
if err != nil {
return nil, err
}

group_log.Debugf("Group <%s> created", grp.Item.GroupId)
return genesisBlock, nil
}

func (grp *Group) JoinGroup(item *quorumpb.GroupItem) error {
group_log.Debugf("<%s> JoinGoup called", item.GroupId)

Expand Down
4 changes: 4 additions & 0 deletions pkg/chainapi/api/joingroup_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ import (
"github.com/rumsystem/quorum/testnode"
)

type JoinGroupParamV2 struct {
Seed string `json:"seed" validate:"required" example:"rum://seed?v=1&e=0&n=0&b=tknSczG2RC6hEBTXZyig7w&c=Za8zI2nAWaTNSvSv6cnPPxHCZef9sGtKtgsZ8iSxj0E&g=SfGcugfLTZ68Hc-xscFwMQ&k=AnRP4sojIvAH-Ugqnd7ZaM1H8j_c1pX6clyeXgAORiGZ&s=mrcA0LDzo54zUujZTINvWM_k2HSifv2T4JfYHAY2EzsCRGdR5vxHbvVNStlJOOBK_ohT6vFGs0FDk2pWYVRPUQE&t=FyvyFrtDGC0&a=timeline.dev&y=group_timeline&u=http%3A%2F%2F1.2.3.4%3A6090%3Fjwt%3DeyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhbGxvd0dyb3VwcyI6WyI0OWYxOWNiYS0wN2NiLTRkOWUtYmMxZC1jZmIxYjFjMTcwMzEiXSwiZXhwIjoxODI3Mzc0MjgyLCJuYW1lIjoiYWxsb3ctNDlmMTljYmEtMDdjYi00ZDllLWJjMWQtY2ZiMWIxYzE3MDMxIiwicm9sZSI6Im5vZGUifQ.rr_tYm0aUdmOeM0EYVzNpKmoNDOpSGzD38s6tjlxuCo"` // seed url
}

type JoinGroupResult struct {
GroupId string `json:"group_id" validate:"required,uuid4" example:"c0020941-e648-40c9-92dc-682645acd17e"`
GroupName string `json:"group_name" validate:"required" example:"demo group"`
Expand Down
37 changes: 37 additions & 0 deletions pkg/chainapi/api/newseed.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package api

import (
"net/http"

"github.com/labstack/echo/v4"
"github.com/rumsystem/quorum/internal/pkg/options"
"github.com/rumsystem/quorum/internal/pkg/utils"
handlers "github.com/rumsystem/quorum/pkg/chainapi/handlers"
_ "github.com/rumsystem/quorum/pkg/pb" //import for swaggo
)

// @Tags Groups
// @Summary CreateGroupUrl
// @Description Create a new group
// @Accept json
// @Produce json
// @Param data body handlers.CreateGroupParam true "GroupInfo"
// @Success 200 {object} handlers.CreateGroupResult
// @Router /api/v1/group [post]
func (h *Handler) NewSeed() echo.HandlerFunc {
return func(c echo.Context) error {
cc := c.(*utils.CustomContext)

params := new(handlers.NewSeedParams)
if err := cc.BindAndValidate(params); err != nil {
return err
}

seed, err := handlers.NewSeed(params, options.GetNodeOptions())
if err != nil {
return err
}

return c.JSON(http.StatusOK, seed)
}
}
2 changes: 2 additions & 0 deletions pkg/chainapi/api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ func StartFullNodeServer(config StartServerParam, signalch chan os.Signal, h *Ha
a := e.Group("/app/api")
r.GET("/quit", quitapp)

r.POST("/v2/group/newseed", h.NewSeed())

r.POST("/v1/group", h.CreateGroupUrl())
r.POST("/v2/group/join", h.JoinGroupV2())
r.POST("/v1/group/leave", h.LeaveGroup)
Expand Down
130 changes: 130 additions & 0 deletions pkg/chainapi/handlers/newseed.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package handlers

import (
"encoding/hex"
"errors"

"github.com/go-playground/validator/v10"
guuid "github.com/google/uuid"
"github.com/rumsystem/quorum/internal/pkg/nodectx"
"github.com/rumsystem/quorum/internal/pkg/options"
localcrypto "github.com/rumsystem/quorum/pkg/crypto"
rumchaindata "github.com/rumsystem/quorum/pkg/data"
"github.com/rumsystem/quorum/pkg/pb"
"google.golang.org/protobuf/proto"
)

type NewSeedParams struct {
AppKey string `from:"app_key" json:"app_key" validate:"required,max=20,min=4" example:"test_app"`
GroupName string `from:"group_name" json:"group_name" validate:"required,max=100,min=2" example:"demo group"`
ConsensusType string `from:"consensus_type" json:"consensus_type" validate:"required,oneof=pos poa" example:"poa"`
EncryptionType string `from:"encryption_type" json:"encryption_type" validate:"required,oneof=public private" example:"public"`
}

type NewSeedResult struct {
AppKey string `json:"app_key" validate:"required" example:"test_app"`
GroupId string `json:"group_id" validate:"required,uuid4" example:"c0020941-e648-40c9-92dc-682645acd17e"`
Seed *pb.GroupSeedRumLite `json:"seed" validate:"required"`
}

const DEFAULT_EPOCH_DURATION = 1000 //ms

func NewSeed(params *NewSeedParams, nodeoptions *options.NodeOptions) (*NewSeedResult, error) {
validate := validator.New()
if err := validate.Struct(params); err != nil {
return nil, err
}

if params.ConsensusType != "poa" {
return nil, errors.New("consensus_type must be poa, other types are not supported in rum-lite")
}

if params.EncryptionType != "public" {
return nil, errors.New("encryption_type must be public, other types are not supported in rum-lite")
}

//create groupid
groupid := guuid.New().String()

//init keystore
ks := nodectx.GetNodeCtx().Keystore

//init ownerpubkey
ownerpubkey, err := initSignKey(groupid, ks, nodeoptions)
if err != nil {
return nil, errors.New("group key can't be decoded, err:" + err.Error())
}

//init cipher key
cipherKey, err := localcrypto.CreateAesKey()
if err != nil {
return nil, err
}

//create genesis block
genesisBlock, err := rumchaindata.CreateGenesisBlockByEthKey(groupid, ownerpubkey, ks, "")
if err != nil {
return nil, err
}

groupConsensusInfo := &pb.PoaGroupConsensusInfo{
EpochDuration: DEFAULT_EPOCH_DURATION,
Producers: []string{ownerpubkey},
CurrEpoch: 0,
CurrBlockId: 0,
}

//initial PublicPoaGroupItem
publicPoaGroup := &pb.PublicPOAGroupItem{
AppKey: params.AppKey,
GroupId: groupid,
GroupName: params.GroupName,
OwnerPubKey: ownerpubkey,
SignPubkey: ownerpubkey,
CipherKey: hex.EncodeToString(cipherKey),
GenesisBlock: genesisBlock,
ConsensusInfo: groupConsensusInfo,
}

//marshal PublicPoaGroupItem
publicPoaGroupByts, err := proto.Marshal(publicPoaGroup)
if err != nil {
return nil, err
} //

//create GroupItemRumLite
groupItem := &pb.GroupItemRumLite{
Type: pb.GroupType_PUBLIC_POA,
GroupData: publicPoaGroupByts,
}

//marshal GroupItemRumLite
groupItemByts, err := proto.Marshal(groupItem)
if err != nil {
return nil, err
}

//create hash
hash := localcrypto.Hash(groupItemByts)

//create signature
signature, err := ks.EthSignByKeyAlias(groupid, hash)
if err != nil {
return nil, err
}

//create GroupSeedRumLite
groupSeed := &pb.GroupSeedRumLite{
Group: groupItem,
Hash: hash,
Signature: signature,
}

result := &NewSeedResult{
AppKey: params.AppKey,
GroupId: groupid,
Seed: groupSeed,
}

return result, nil
}
13 changes: 6 additions & 7 deletions pkg/data/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"time"
)

func CreateBlockByEthKey(parentBlk *quorumpb.Block, consensusInfo *quorumpb.ConsensusInfo, trxs []*quorumpb.Trx, groupPublicKey string, keystore localcrypto.Keystore, keyalias string, opts ...string) (*quorumpb.Block, error) {
func CreateBlockByEthKey(parentBlk *quorumpb.Block, trxs []*quorumpb.Trx, groupPublicKey string, keystore localcrypto.Keystore, keyalias string, opts ...string) (*quorumpb.Block, error) {
newBlock := &quorumpb.Block{
GroupId: parentBlk.GroupId,
BlockId: parentBlk.BlockId + 1,
Expand Down Expand Up @@ -51,15 +51,16 @@ func CreateBlockByEthKey(parentBlk *quorumpb.Block, consensusInfo *quorumpb.Cons
return newBlock, nil
}

func CreateGenesisBlockByEthKey(groupId string, consensusInfo *quorumpb.ConsensusInfo, forkTrx *quorumpb.Trx, groupPublicKey string, keystore localcrypto.Keystore, keyalias string) (*quorumpb.Block, error) {
func CreateGenesisBlockByEthKey(groupId string, producerPubkey string, keystore localcrypto.Keystore, keyalias string) (*quorumpb.Block, error) {
genesisBlock := &quorumpb.Block{
GroupId: groupId,
BlockId: 0,
PrevHash: nil,
ProducerPubkey: groupPublicKey,
Trxs: []*quorumpb.Trx{forkTrx},
ProducerPubkey: producerPubkey,
Trxs: nil,
TimeStamp: time.Now().UnixNano(),
Consensus: consensusInfo,
BlockHash: nil,
ProducerSign: nil,
}

bbytes, err := proto.Marshal(genesisBlock)
Expand Down Expand Up @@ -96,7 +97,6 @@ func ValidBlockWithParent(newBlock, parentBlock *quorumpb.Block) (bool, error) {
ProducerPubkey: newBlock.ProducerPubkey,
Trxs: newBlock.Trxs,
TimeStamp: newBlock.TimeStamp,
Consensus: newBlock.Consensus,
BlockHash: nil,
ProducerSign: nil,
}
Expand Down Expand Up @@ -157,7 +157,6 @@ func ValidGenesisBlock(genesisBlock *quorumpb.Block) (bool, error) {
ProducerPubkey: genesisBlock.ProducerPubkey,
Trxs: genesisBlock.Trxs,
TimeStamp: genesisBlock.TimeStamp,
Consensus: genesisBlock.Consensus,
BlockHash: nil,
ProducerSign: nil,
}
Expand Down
Loading

0 comments on commit 328f23e

Please sign in to comment.