diff --git a/daemon/algod/api/algod.oas2.json b/daemon/algod/api/algod.oas2.json index 2b03eb3661..387effde22 100644 --- a/daemon/algod/api/algod.oas2.json +++ b/daemon/algod/api/algod.oas2.json @@ -1167,9 +1167,9 @@ ], "responses": { "200": { - "description": "An empty JSON object is returned if the generation process was started. Currently no status is available.", + "description": "The participation ID. Currently no status is available.", "schema": { - "$ref": "#/definitions/ParticipationKey" + "type": "string" } }, "400": { diff --git a/daemon/algod/api/algod.oas3.yml b/daemon/algod/api/algod.oas3.yml index de47479e22..9b7ec0a37d 100644 --- a/daemon/algod/api/algod.oas3.yml +++ b/daemon/algod/api/algod.oas3.yml @@ -5833,7 +5833,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ParticipationKey" + "type": "string" } } }, diff --git a/daemon/algod/api/server/v2/generated/participating/private/routes.go b/daemon/algod/api/server/v2/generated/participating/private/routes.go index 353cc75599..3a53efec1e 100644 --- a/daemon/algod/api/server/v2/generated/participating/private/routes.go +++ b/daemon/algod/api/server/v2/generated/participating/private/routes.go @@ -469,15 +469,15 @@ var swaggerSpec = []string{ "R599uukvQF+JHNgb2FRKcy3KHftJNg9vbszjzooimUC2e/QP8rj5bJvlqoAVyMwzsGyhip2vyDPrTHAJ", "ZC0bCDKnwbrU0RhGuGewW6WklTYcfPbsbSoswj9vrOpFKXJGlnU0LVXcriPLT5PRs8v85nssE/NE1nhW", "iLJusjnYa+VfSw8vlMjaYhUz/9B48eBBFHbHroUs1PWDkwDuP2pAPu/hDdPMEgBGMb7DAkmtw9ABOABr", - "bD70NE7Bzp7JX/KbzV3yY6d+/yvq7EPpNSGthoR6/3nx4w/RY0UyRFC8ED6VI8rGdw1aYbz+NceAUaqz", - "+JxMROUOH91abmvTKfF28sc19cfVcPur4dsmwzIVd7NYtWnIsaKr4mSSPJxk/R86f3qzxoyitVN5kd3v", - "jLMVFuYc3l+LHTt/MVBuqVv/rH61w6a9SyNxHfRBPOpeGOE++yQet5CVsk3MOi3qDxn0Dxn0Vnrt5MMz", - "RbVNGp6oXC4fqGvzUPm28y4Ic5tjBNgAlCnmqd/0+H464cHnYIeCRR8oeUUfzX+wiD9YxO1YxLeQOIx4", - "aj3TSBDdcaawqQwDMy0VnQjMIHWE5nXJdfRe+JCF+wxHTGuKvwrX+NT2vCSuyJyHzwoExdMmNvBuTXx/", - "sLw/WN7vh+WdHWY0XcHk1kaxS9hteNWYwsy6toW6jhzoCAvFwg9dgKT49/8+vebCZkulfUUfvrSgh50t", - "8PLUl+/u/dpWzBx8wTKg0Y9xrrrkr6e869Ps+tUd6x3rOHC6p756v/JIo5BiIXxuQ/riEDlk+01w3Nv3", - "jmUb0FfhRmgjvp6dnmLOnbUy9nT2cf6hFw0Wf3zfkMeH5h7xZPIR6UJpsRKSl5kPncjaqK4nJ49mH/9v", - "AAAA//+GfTsjMx0BAA==", + "bD70NE7Bzp7JX/KbzV3yY6d+/2vboJqMef958eMP0WtEsjRQQBC+hSPSxYcLWmFA/jXHiFAqpPicbEDl", + "Dl/VWm5r06nhdvLHPfQH77897/+2SaFM1dsslmUasqToLjiZJPAmefuHzp/ebjGjcOxU4mP3O+NshZU3", + "hxfUYsfOXwy0V+rWvxK+2mHT3q2Q4Pd9EI9i/CPsZZ9I4xayUrYJSqdF/SFk/iFk3kpxnXx4puiuScsS", + "1cPlA31sHkrbdh7+YPJyDPEagDLF/vSbHt872fihbStly6Ik61Cw6ANlp+ij+Q8W8QeLuB2L+BYShxFP", + "rWcaCaI7ztY1lWFgKqWiE2IZpI7QvC65jh4EHzJhn+GIaVXwV+Ean9pgl8QV2evw3YCggNnEBt6tDe8P", + "lvcHy/v9sLyzw4ymK5jc2up1CbsNrxpbl1nXtlDXkYccYaFg96GPjxT//t+n11zYbKm0L9nDlxb0sLMF", + "Xp76+ty9X9uSmIMvWOcz+jFORpf89ZR3nZZdx7ljvWMdB1711FfvOB5pFHIohM9tzF4cA4dsv4l+e/ve", + "sWwD+ircCG1I17PTU0yqs1bGns4+zj/0wr3ij+8b8vjQ3COeTD4iXSgtVkLyMvOxEVkbtvXk5NHs4/8N", + "AAD//1nr4yEUHQEA", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/daemon/algod/api/server/v2/handlers.go b/daemon/algod/api/server/v2/handlers.go index c8f7a140a3..e41ec20934 100644 --- a/daemon/algod/api/server/v2/handlers.go +++ b/daemon/algod/api/server/v2/handlers.go @@ -264,7 +264,7 @@ func (v2 *Handlers) GetParticipationKeys(ctx echo.Context) error { return ctx.JSON(http.StatusOK, response) } -func (v2 *Handlers) generateKeyHandler(address string, params model.GenerateParticipationKeysParams) (model.ParticipationKey, error) { +func (v2 *Handlers) generateKeyHandler(address string, params model.GenerateParticipationKeysParams) error { installFunc := func(path string) error { bytes, err := os.ReadFile(path) if err != nil { @@ -280,38 +280,44 @@ func (v2 *Handlers) generateKeyHandler(address string, params model.GeneratePart v2.Log.Infof("Installed participation key %s", partID) return err } - partKeys, _, err := participation.GenParticipationKeysTo(address, params.First, params.Last, nilToZero(params.Dilution), "", installFunc) - if err != nil { - return model.ParticipationKey{}, err - } - nodePartKey, err := v2.Node.GetParticipationKey(partKeys.ID()) - if err != nil { - return model.ParticipationKey{}, err - } - - return convertParticipationRecord(nodePartKey), nil + _, _, err := participation.GenParticipationKeysTo(address, params.First, params.Last, nilToZero(params.Dilution), "", installFunc) + return err } // GenerateParticipationKeys generates and installs participation keys to the node. // (POST /v2/participation/generate/{address}) func (v2 *Handlers) GenerateParticipationKeys(ctx echo.Context, address string, params model.GenerateParticipationKeysParams) error { + addr, err := basics.UnmarshalChecksumAddress(address) + if err != nil { + return badRequest(ctx, err, err.Error(), v2.Log) + } if !v2.KeygenLimiter.TryAcquire(1) { err := fmt.Errorf("participation key generation already in progress") return badRequest(ctx, err, err.Error(), v2.Log) } - // Generate the keys on the main thread to block response - // KeysBuilder already handles coroutines, this response feedback - // is necessary for end users - part, err := v2.generateKeyHandler(address, params) - defer v2.KeygenLimiter.Release(1) + // Semaphore was acquired, generate the key. + go func() { + defer v2.KeygenLimiter.Release(1) + err := v2.generateKeyHandler(address, params) + if err != nil { + v2.Log.Warnf("Error generating participation keys: %v", err) + } + }() - if err != nil { - return badRequest(ctx, err, err.Error(), v2.Log) + firstRound := basics.Round(params.First) + lastRound := basics.Round(params.Last) + keyDilution := nilToZero(params.Dilution) + if keyDilution == 0 { + keyDilution = account.DefaultKeyDilution(firstRound, lastRound) } - - // ParticipationKey. Returns the stored participation key. - return ctx.JSON(http.StatusOK, part) + identity := account.ParticipationKeyIdentity{ + Parent: addr, + FirstValid: firstRound, + LastValid: lastRound, + KeyDilution: keyDilution, + } + return ctx.JSON(http.StatusOK, identity.ID().String()) } // AddParticipationKey Add a participation key to the node diff --git a/data/account/msgp_gen.go b/data/account/msgp_gen.go index 36459a83f3..9f4595b7f5 100644 --- a/data/account/msgp_gen.go +++ b/data/account/msgp_gen.go @@ -5,7 +5,6 @@ package account import ( "github.com/algorand/msgp/msgp" - "github.com/algorand/go-algorand/crypto" "github.com/algorand/go-algorand/crypto/merklesignature" "github.com/algorand/go-algorand/data/basics" ) @@ -36,8 +35,8 @@ import ( func (z *ParticipationKeyIdentity) MarshalMsg(b []byte) (o []byte) { o = msgp.Require(b, z.Msgsize()) // omitempty: check for empty values - zb0001Len := uint32(6) - var zb0001Mask uint8 /* 7 bits */ + zb0001Len := uint32(4) + var zb0001Mask uint8 /* 5 bits */ if (*z).Parent.MsgIsZero() { zb0001Len-- zb0001Mask |= 0x2 @@ -54,14 +53,6 @@ func (z *ParticipationKeyIdentity) MarshalMsg(b []byte) (o []byte) { zb0001Len-- zb0001Mask |= 0x10 } - if (*z).VoteID.MsgIsZero() { - zb0001Len-- - zb0001Mask |= 0x20 - } - if (*z).VRFSK.MsgIsZero() { - zb0001Len-- - zb0001Mask |= 0x40 - } // variable map header, size zb0001Len o = append(o, 0x80|uint8(zb0001Len)) if zb0001Len != 0 { @@ -85,16 +76,6 @@ func (z *ParticipationKeyIdentity) MarshalMsg(b []byte) (o []byte) { o = append(o, 0xa2, 0x6c, 0x76) o = (*z).LastValid.MarshalMsg(o) } - if (zb0001Mask & 0x20) == 0 { // if not empty - // string "vote-id" - o = append(o, 0xa7, 0x76, 0x6f, 0x74, 0x65, 0x2d, 0x69, 0x64) - o = (*z).VoteID.MarshalMsg(o) - } - if (zb0001Mask & 0x40) == 0 { // if not empty - // string "vrfsk" - o = append(o, 0xa5, 0x76, 0x72, 0x66, 0x73, 0x6b) - o = (*z).VRFSK.MarshalMsg(o) - } } return } @@ -130,22 +111,6 @@ func (z *ParticipationKeyIdentity) UnmarshalMsgWithState(bts []byte, st msgp.Unm return } } - if zb0001 > 0 { - zb0001-- - bts, err = (*z).VRFSK.UnmarshalMsgWithState(bts, st) - if err != nil { - err = msgp.WrapError(err, "struct-from-array", "VRFSK") - return - } - } - if zb0001 > 0 { - zb0001-- - bts, err = (*z).VoteID.UnmarshalMsgWithState(bts, st) - if err != nil { - err = msgp.WrapError(err, "struct-from-array", "VoteID") - return - } - } if zb0001 > 0 { zb0001-- bts, err = (*z).FirstValid.UnmarshalMsgWithState(bts, st) @@ -199,18 +164,6 @@ func (z *ParticipationKeyIdentity) UnmarshalMsgWithState(bts []byte, st msgp.Unm err = msgp.WrapError(err, "Parent") return } - case "vrfsk": - bts, err = (*z).VRFSK.UnmarshalMsgWithState(bts, st) - if err != nil { - err = msgp.WrapError(err, "VRFSK") - return - } - case "vote-id": - bts, err = (*z).VoteID.UnmarshalMsgWithState(bts, st) - if err != nil { - err = msgp.WrapError(err, "VoteID") - return - } case "fv": bts, err = (*z).FirstValid.UnmarshalMsgWithState(bts, st) if err != nil { @@ -252,18 +205,18 @@ func (_ *ParticipationKeyIdentity) CanUnmarshalMsg(z interface{}) bool { // Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message func (z *ParticipationKeyIdentity) Msgsize() (s int) { - s = 1 + 5 + (*z).Parent.Msgsize() + 6 + (*z).VRFSK.Msgsize() + 8 + (*z).VoteID.Msgsize() + 3 + (*z).FirstValid.Msgsize() + 3 + (*z).LastValid.Msgsize() + 3 + msgp.Uint64Size + s = 1 + 5 + (*z).Parent.Msgsize() + 3 + (*z).FirstValid.Msgsize() + 3 + (*z).LastValid.Msgsize() + 3 + msgp.Uint64Size return } // MsgIsZero returns whether this is a zero value func (z *ParticipationKeyIdentity) MsgIsZero() bool { - return ((*z).Parent.MsgIsZero()) && ((*z).VRFSK.MsgIsZero()) && ((*z).VoteID.MsgIsZero()) && ((*z).FirstValid.MsgIsZero()) && ((*z).LastValid.MsgIsZero()) && ((*z).KeyDilution == 0) + return ((*z).Parent.MsgIsZero()) && ((*z).FirstValid.MsgIsZero()) && ((*z).LastValid.MsgIsZero()) && ((*z).KeyDilution == 0) } // MaxSize returns a maximum valid message size for this message type func ParticipationKeyIdentityMaxSize() (s int) { - s = 1 + 5 + basics.AddressMaxSize() + 6 + crypto.VrfPrivkeyMaxSize() + 8 + crypto.OneTimeSignatureVerifierMaxSize() + 3 + basics.RoundMaxSize() + 3 + basics.RoundMaxSize() + 3 + msgp.Uint64Size + s = 1 + 5 + basics.AddressMaxSize() + 3 + basics.RoundMaxSize() + 3 + basics.RoundMaxSize() + 3 + msgp.Uint64Size return } diff --git a/data/account/participation.go b/data/account/participation.go index a4dcf04b74..43469078c0 100644 --- a/data/account/participation.go +++ b/data/account/participation.go @@ -66,12 +66,10 @@ type Participation struct { type ParticipationKeyIdentity struct { _struct struct{} `codec:",omitempty,omitemptyarray"` - Parent basics.Address `codec:"addr"` - VRFSK crypto.VrfPrivkey `codec:"vrfsk"` - VoteID crypto.OneTimeSignatureVerifier `codec:"vote-id"` - FirstValid basics.Round `codec:"fv"` - LastValid basics.Round `codec:"lv"` - KeyDilution uint64 `codec:"kd"` + Parent basics.Address `codec:"addr"` + FirstValid basics.Round `codec:"fv"` + LastValid basics.Round `codec:"lv"` + KeyDilution uint64 `codec:"kd"` } // ToBeHashed implements the Hashable interface. @@ -92,12 +90,6 @@ func (part Participation) ID() ParticipationID { LastValid: part.LastValid, KeyDilution: part.KeyDilution, } - if part.VRF != nil { - copy(idData.VRFSK[:], part.VRF.SK[:]) - } - if part.Voting != nil { - copy(idData.VoteID[:], part.Voting.OneTimeSignatureVerifier[:]) - } return idData.ID() } diff --git a/data/accountManager.go b/data/accountManager.go index 8e10cb35c7..8cca0bda8d 100644 --- a/data/accountManager.go +++ b/data/accountManager.go @@ -131,8 +131,6 @@ func (manager *AccountManager) AddParticipation(participation account.PersistedP Parent: address, FirstValid: first, LastValid: last, - VRFSK: participation.VRF.SK, - VoteID: participation.Voting.OneTimeSignatureVerifier, KeyDilution: participation.KeyDilution, }