github.com/decred/politeia@v1.4.0/politeiawww/api/ticketvote/v1/v1.go (about) 1 // Copyright (c) 2020-2021 The Decred developers 2 // Use of this source code is governed by an ISC 3 // license that can be found in the LICENSE file. 4 5 package v1 6 7 import "fmt" 8 9 const ( 10 // APIRoute is prefixed onto all routes defined in this package. 11 APIRoute = "/ticketvote/v1" 12 13 // RoutePolicy returns the policy for the ticketvote API. 14 RoutePolicy = "/policy" 15 16 // RouteAuthorize authorizes a record vote. 17 RouteAuthorize = "/authorize" 18 19 // RouteStart starts a record vote. 20 RouteStart = "/start" 21 22 // RouteCastBallot casts ballot of votes. 23 RouteCastBallot = "/castballot" 24 25 // RouteDetails returns the vote details for a record vote. 26 RouteDetails = "/details" 27 28 // RouteResults returns the vote results for a record vote. 29 RouteResults = "/results" 30 31 // RouteSummaries returns the vote summary for a page of record 32 // votes. 33 RouteSummaries = "/summaries" 34 35 // RouteSubmissions returns the submissions of a runoff vote. 36 RouteSubmissions = "/submissions" 37 38 // RouteInventory returns the tokens of public records in the inventory 39 // categorized by vote status. 40 RouteInventory = "/inventory" 41 42 // RouteTimestamps returns the timestamps for ticket vote data. 43 RouteTimestamps = "/timestamps" 44 ) 45 46 // ErrorCodeT represents a user error code. 47 type ErrorCodeT uint32 48 49 const ( 50 // ErrorCodeInvalid is an invalid error code. 51 ErrorCodeInvalid ErrorCodeT = 0 52 53 // ErrorCodeInputInvalid is returned when there is an error 54 // while prasing a command payload. 55 ErrorCodeInputInvalid ErrorCodeT = 1 56 57 // ErrorCodePublicKeyInvalid is returned when a public key used 58 // in a signature is not valid. 59 ErrorCodePublicKeyInvalid ErrorCodeT = 2 60 61 // ErrorCodeUnauthorized is returned when the user is not authorized. 62 ErrorCodeUnauthorized ErrorCodeT = 3 63 64 // ErrorCodeRecordNotFound is returned when a record not found. 65 ErrorCodeRecordNotFound ErrorCodeT = 4 66 67 // ErrorCodeRecordLocked is returned when a record is locked. 68 ErrorCodeRecordLocked ErrorCodeT = 5 69 70 // ErrorCodeTokenInvalid is returned when a token is invalid. 71 ErrorCodeTokenInvalid ErrorCodeT = 6 72 73 // ErrorCodePageSizeExceeded is returned when the request's page size 74 // exceeds the maximum page size of the request. 75 ErrorCodePageSizeExceeded ErrorCodeT = 7 76 77 // ErrorCodeDuplicatePayload is returned when a user tries to submit a 78 // duplicate payload for the ticketvote plugin, where it tries to write 79 // data that already exists. Timestamp data relies on the hash of the 80 // payload, therefore duplicate payloads are not allowed since they will 81 // cause collisions. 82 ErrorCodeDuplicatePayload ErrorCodeT = 8 83 84 // ErrorCodeLast is used by unit tests to verify that all error codes have 85 // a human readable entry in the ErrorCodes map. This error will never be 86 // returned. 87 ErrorCodeLast ErrorCodeT = 9 88 ) 89 90 var ( 91 // ErrorCodes contains the human readable errors. 92 ErrorCodes = map[ErrorCodeT]string{ 93 ErrorCodeInvalid: "error invalid", 94 ErrorCodeInputInvalid: "input invalid", 95 ErrorCodePublicKeyInvalid: "public key invalid", 96 ErrorCodeUnauthorized: "unauthorized", 97 ErrorCodeRecordNotFound: "record not found", 98 ErrorCodeRecordLocked: "record locked", 99 ErrorCodeTokenInvalid: "token is invalid", 100 ErrorCodePageSizeExceeded: "page size exceeded", 101 ErrorCodeDuplicatePayload: "duplicate payload", 102 } 103 ) 104 105 // UserErrorReply is the reply that the server returns when it encounters an 106 // error that is caused by something that the user did (malformed input, bad 107 // timing, etc). The HTTP status code will be 400. 108 type UserErrorReply struct { 109 ErrorCode ErrorCodeT `json:"errorcode"` 110 ErrorContext string `json:"errorcontext,omitempty"` 111 } 112 113 // Error satisfies the error interface. 114 func (e UserErrorReply) Error() string { 115 return fmt.Sprintf("user error code: %v", e.ErrorCode) 116 } 117 118 // PluginErrorReply is the reply that the server returns when it encounters 119 // a plugin error. 120 type PluginErrorReply struct { 121 PluginID string `json:"pluginid"` 122 ErrorCode uint32 `json:"errorcode"` 123 ErrorContext string `json:"errorcontext,omitempty"` 124 } 125 126 // Error satisfies the error interface. 127 func (e PluginErrorReply) Error() string { 128 return fmt.Sprintf("plugin %v error code: %v", e.PluginID, e.ErrorCode) 129 } 130 131 // ServerErrorReply is the reply that the server returns when it encounters an 132 // unrecoverable error while executing a command. The HTTP status code will be 133 // 500 and the ErrorCode field will contain a UNIX timestamp that the user can 134 // provide to the server admin to track down the error details in the logs. 135 type ServerErrorReply struct { 136 ErrorCode int64 `json:"errorcode"` 137 } 138 139 // Error satisfies the error interface. 140 func (e ServerErrorReply) Error() string { 141 return fmt.Sprintf("server error: %v", e.ErrorCode) 142 } 143 144 // Policy requests the ticketvote policy. 145 type Policy struct{} 146 147 // PolicyReply is the reply to the Policy command. 148 type PolicyReply struct { 149 LinkByPeriodMin int64 `json:"linkbyperiodmin"` // In seconds 150 LinkByPeriodMax int64 `json:"linkbyperiodmax"` // In seconds 151 VoteDurationMin uint32 `json:"votedurationmin"` // In blocks 152 VoteDurationMax uint32 `json:"votedurationmax"` // In blocks 153 SummariesPageSize uint32 `json:"summariespagesize"` 154 InventoryPageSize uint32 `json:"inventorypagesize"` 155 TimestampsPageSize uint32 `json:"timestampspagesize"` 156 } 157 158 // AuthActionT represents an Authorize action. 159 type AuthActionT string 160 161 const ( 162 // AuthActionAuthorize is used to authorize a record vote. 163 AuthActionAuthorize AuthActionT = "authorize" 164 165 // AuthActionRevoke is used to revoke a previous authorization. 166 AuthActionRevoke AuthActionT = "revoke" 167 ) 168 169 // Authorize authorizes a record vote or revokes a previous vote 170 // authorization. Not all vote types require an authorization. 171 // 172 // Signature contains the client signature of the Token+Version+Action. 173 type Authorize struct { 174 Token string `json:"token"` 175 Version uint32 `json:"version"` 176 Action AuthActionT `json:"action"` 177 PublicKey string `json:"publickey"` 178 Signature string `json:"signature"` 179 } 180 181 // AuthorizeReply is the reply to the Authorize command. 182 // 183 // Receipt is the server signature of the client signature. This is proof that 184 // the server received and processed the Authorize command. 185 type AuthorizeReply struct { 186 Timestamp int64 `json:"timestamp"` 187 Receipt string `json:"receipt"` 188 } 189 190 // VoteT represents a vote type. 191 type VoteT uint32 192 193 const ( 194 // VoteTypeInvalid represents and invalid vote type. 195 VoteTypeInvalid VoteT = 0 196 197 // VoteTypeStandard is used to indicate a simple approve or reject 198 // vote where the winner is the voting option that has met the 199 // specified quorum and pass requirements. Standard votes require 200 // an authorization from the record author before the voting period 201 // can be started by an admin. 202 VoteTypeStandard VoteT = 1 203 204 // VoteTypeRunoff specifies a runoff vote that multiple records 205 // compete in. All records are voted on like normal and all votes 206 // are simple approve/reject votes, but there can only be one 207 // winner in a runoff vote. The winner is the record that meets 208 // the quorum requirement, meets the pass requirement, and that has 209 // the most net yes votes. The winning record is considered 210 // approved and all other records are considered to be rejected. 211 // If no records meet the quorum and pass requirements then all 212 // records are considered rejected. Note, in a runoff vote it is 213 // possible for a record to meet both the quorum and pass 214 // requirements but still be rejected if it does not have the most 215 // net yes votes. 216 VoteTypeRunoff VoteT = 2 217 218 // VoteTypeLast unit test only. 219 VoteTypeLast VoteT = 3 220 ) 221 222 var ( 223 // VoteTypes contains the human readable vote types. 224 VoteTypes = map[VoteT]string{ 225 VoteTypeInvalid: "invalid vote type", 226 VoteTypeStandard: "standard", 227 VoteTypeRunoff: "runoff", 228 } 229 ) 230 231 const ( 232 // VoteOptionIDApprove is the vote option ID that indicates the 233 // record should be approved. Standard votes and runoff vote 234 // submissions are required to use this vote option ID. 235 VoteOptionIDApprove = "yes" 236 237 // VoteOptionIDReject is the vote option ID that indicates the 238 // record should be rejected. Standard votes and runoff vote 239 // submissions are required to use this vote option ID. 240 VoteOptionIDReject = "no" 241 ) 242 243 // VoteStatusT represents a vote status. 244 type VoteStatusT uint32 245 246 const ( 247 // VoteStatusInvalid represents an invalid vote status. 248 VoteStatusInvalid VoteStatusT = 0 249 250 // VoteStatusUnauthorized represents a vote that has not been 251 // authorized yet. Some vote types require prior authorization from 252 // the record author before an admin can start the voting period. 253 VoteStatusUnauthorized VoteStatusT = 1 254 255 // VoteStatusAuthorized represents a vote that has been authorized. 256 // Some vote types require prior authorization from the record 257 // author before an admin can start the voting period. 258 VoteStatusAuthorized VoteStatusT = 2 259 260 // VoteStatusStarted represents a vote that has been started and 261 // is still ongoing. 262 VoteStatusStarted VoteStatusT = 3 263 264 // VoteStatusFinished indicates the ticket vote has finished. This 265 // vote status is used for vote types that do not have a clear 266 // approved or rejected outcome, such as multiple choice votes. 267 VoteStatusFinished VoteStatusT = 4 268 269 // VoteStatusApproved indicates that a vote has finished and the 270 // vote has met the criteria for being approved. This vote status 271 // is only used when the vote type allows for a clear approved or 272 // rejected outcome. 273 VoteStatusApproved VoteStatusT = 5 274 275 // VoteStatusRejected indicates that a vote has finished and the 276 // vote did NOT the criteria for being approved. This vote status 277 // is only used when the vote type allows for a clear approved or 278 // rejected outcome. 279 VoteStatusRejected VoteStatusT = 6 280 281 // VoteStatusIneligible indicates that a record is not eligible to 282 // be voted on. This happens when a record is censored or archived. 283 VoteStatusIneligible VoteStatusT = 7 284 285 // VoteStatusLast unit test only. 286 VoteStatusLast VoteStatusT = 8 287 ) 288 289 var ( 290 // VoteStatuses contains the human readable vote statuses. 291 VoteStatuses = map[VoteStatusT]string{ 292 VoteStatusInvalid: "invalid", 293 VoteStatusUnauthorized: "unauthorized", 294 VoteStatusAuthorized: "authorized", 295 VoteStatusStarted: "started", 296 VoteStatusFinished: "finished", 297 VoteStatusApproved: "approved", 298 VoteStatusRejected: "rejected", 299 VoteStatusIneligible: "ineligible", 300 } 301 ) 302 303 // VoteMetadata that is specified by the user on record submission in order to 304 // host or participate in certain types of votes. It is attached to a record 305 // submission as a metadata stream. 306 type VoteMetadata struct { 307 // LinkBy is set when the user intends for the record to be the 308 // parent record in a runoff vote. It is a UNIX timestamp that 309 // serves as the deadline for other records to declare their intent 310 // to participate in the runoff vote. 311 LinkBy int64 `json:"linkby,omitempty"` 312 313 // LinkTo is the censorship token of a runoff vote parent record. 314 // It is set when a record is being submitted as a vote options in 315 // the runoff vote. 316 LinkTo string `json:"linkto,omitempty"` 317 } 318 319 // VoteOption describes a single vote option. 320 type VoteOption struct { 321 ID string `json:"id"` // Single, unique word (e.g. yes) 322 Description string `json:"description"` // Longer description of the vote 323 Bit uint64 `json:"bit"` // Bit used for this option 324 } 325 326 // VoteParams contains all client defined vote params required by server to 327 // start a record vote. 328 type VoteParams struct { 329 Token string `json:"token"` // Record token 330 Version uint32 `json:"version"` // Record version 331 Type VoteT `json:"type"` // Vote type 332 Mask uint64 `json:"mask"` // Valid vote bits 333 Duration uint32 `json:"duration"` // Duration in blocks 334 335 // QuorumPercentage is the percent of elligible votes required for 336 // the vote to meet a quorum. 337 QuorumPercentage uint32 `json:"quorumpercentage"` 338 339 // PassPercentage is the percent of cast votes required for a vote 340 // option to be considered as passing. 341 PassPercentage uint32 `json:"passpercentage"` 342 343 Options []VoteOption `json:"options"` 344 345 // Parent is the token of the parent record. This field will only 346 // be populated for runoff votes. 347 Parent string `json:"parent,omitempty"` 348 } 349 350 // StartDetails is the structure that is provided when starting a record 351 // vote. 352 // 353 // Signature is the signature of a SHA256 digest of the JSON encoded 354 // VoteParams. 355 type StartDetails struct { 356 Params VoteParams `json:"params"` 357 PublicKey string `json:"publickey"` 358 Signature string `json:"signature"` 359 } 360 361 // Start starts a record vote or multiple record votes if the vote is a runoff 362 // vote. 363 // 364 // Standard votes require that the vote have been authorized by the record 365 // author before an admin will able to start the voting process. The 366 // StartDetails list should only contain a single StartDetails. 367 // 368 // Runoff votes can be started by an admin at any point once the RFP link by 369 // deadline has expired. Runoff votes DO NOT require the votes to have been 370 // authorized by the submission authors prior to an admin starting the runoff 371 // vote. All public, non-abandoned RFP submissions should be included in the 372 // list of StartDetails. 373 type Start struct { 374 Starts []StartDetails `json:"starts"` 375 } 376 377 // StartReply is the reply to the Start command. 378 // 379 // Receipt is the server signature of ClientSignature+StartBlockHash. 380 type StartReply struct { 381 Receipt string `json:"receipt"` 382 StartBlockHash string `json:"startblockhash"` 383 StartBlockHeight uint32 `json:"startblockheight"` 384 EndBlockHeight uint32 `json:"endblockheight"` 385 EligibleTickets []string `json:"eligibletickets"` 386 } 387 388 // VoteErrorT represents an error that occurred while attempting to cast a 389 // ticket vote. 390 type VoteErrorT int 391 392 const ( 393 // VoteErrorInvalid is an invalid vote error. 394 VoteErrorInvalid VoteErrorT = 0 395 396 // VoteErrorInternalError is returned when an internal server error 397 // occurred while attempting to cast a vote. 398 VoteErrorInternalError VoteErrorT = 1 399 400 // VoteErrorTokenInvalid is returned when a cast vote token is an 401 // invalid record token. 402 VoteErrorTokenInvalid VoteErrorT = 2 403 404 // VoteErrorRecordNotFound is returned when a cast vote token does 405 // not/correspond to a record. 406 VoteErrorRecordNotFound VoteErrorT = 3 407 408 // VoteErrorMultipleRecordVotes is returned when a ballot contains 409 // cast votes for multiple records. A ballot can only contain votes 410 // for a single record at a time. 411 VoteErrorMultipleRecordVotes VoteErrorT = 4 412 413 // VoteErrorVoteStatusInvalid is returned when a vote is cast on a record 414 // that is not being actively voted on. 415 VoteErrorVoteStatusInvalid VoteErrorT = 5 416 417 // VoteErrorVoteBitInvalid is returned when a cast vote's vote bit 418 // is not a valid vote option. 419 VoteErrorVoteBitInvalid VoteErrorT = 6 420 421 // VoteErrorSignatureInvalid is returned when a cast vote signature 422 // is invalid. 423 VoteErrorSignatureInvalid VoteErrorT = 7 424 425 // VoteErrorTicketNotEligible is returned when attempting to cast 426 // a vote using a dcr ticket that is not eligible. 427 VoteErrorTicketNotEligible VoteErrorT = 8 428 429 // VoteErrorTicketAlreadyVoted is returned when attempting to cast 430 // a vote using a dcr ticket that has already voted. 431 VoteErrorTicketAlreadyVoted VoteErrorT = 9 432 ) 433 434 // CastVote is a signed ticket vote. 435 type CastVote struct { 436 Token string `json:"token"` // Record token 437 Ticket string `json:"ticket"` // Ticket ID 438 VoteBit string `json:"votebit"` // Selected vote bit, hex encoded 439 Signature string `json:"signature"` // Signature of Token+Ticket+VoteBit 440 } 441 442 // CastVoteReply contains the receipt for the cast vote. 443 type CastVoteReply struct { 444 Ticket string `json:"ticket"` // Ticket ID 445 Receipt string `json:"receipt"` // Server signature of client signature 446 447 // The follwing fields will only be present if an error occurred 448 // while attempting to cast the vote. 449 ErrorCode *VoteErrorT `json:"errorcode,omitempty"` 450 ErrorContext string `json:"errorcontext,omitempty"` 451 } 452 453 // CastBallot casts a ballot of votes. A ballot can only contain the votes for 454 // a single record. 455 type CastBallot struct { 456 Votes []CastVote `json:"votes"` 457 } 458 459 // CastBallotReply is a reply to a batched list of votes. 460 type CastBallotReply struct { 461 Receipts []CastVoteReply `json:"receipts"` 462 } 463 464 // AuthDetails contains the details of a vote authorization. 465 // 466 // Signature is the client signature of the Token+Version+Action. 467 type AuthDetails struct { 468 Token string `json:"token"` // Record token 469 Version uint32 `json:"version"` // Record version 470 Action string `json:"action"` // Authorization or revoke 471 PublicKey string `json:"publickey"` // Public key used for signature 472 Signature string `json:"signature"` // Client signature 473 Timestamp int64 `json:"timestamp"` // Server timestamp 474 Receipt string `json:"receipt"` // Server sig of client sig 475 } 476 477 // VoteDetails contains the details of a record vote. A vote details with the 478 // eligible tickets snapshot will be ~0.35MB. 479 // 480 // Signature is the client signature of the SHA256 digest of the JSON encoded 481 // VoteParams struct. 482 // 483 // Receipt is the server signature of ClientSignature+StartBlockHash. 484 type VoteDetails struct { 485 Params VoteParams `json:"params"` 486 PublicKey string `json:"publickey"` 487 Signature string `json:"signature"` 488 Receipt string `json:"receipt"` 489 StartBlockHeight uint32 `json:"startblockheight"` 490 StartBlockHash string `json:"startblockhash"` 491 EndBlockHeight uint32 `json:"endblockheight"` 492 EligibleTickets []string `json:"eligibletickets"` // Ticket hashes 493 } 494 495 // Details requests the vote details for a record vote. 496 type Details struct { 497 Token string `json:"token"` 498 } 499 500 // DetailsReply is the reply to the Details command. 501 type DetailsReply struct { 502 Auths []AuthDetails `json:"auths"` 503 Vote *VoteDetails `json:"vote"` 504 } 505 506 // CastVoteDetails contains the details of a cast vote. 507 // 508 // Signature is the client signature of the Token+Ticket+VoteBit. The client 509 // uses the ticket's largest commitment address to create the signature. The 510 // receipt is the server signature of the client signature. 511 type CastVoteDetails struct { 512 Token string `json:"token"` // Record token 513 Ticket string `json:"ticket"` // Ticket hash 514 VoteBit string `json:"votebit"` // Selected vote bit, hex encoded 515 Address string `json:"address"` // Address used in client signature 516 Signature string `json:"signature"` // Client signature 517 Receipt string `json:"receipt"` // Server sig of client sig 518 Timestamp int64 `json:"timestamp"` // Unix timestamp 519 } 520 521 // Results returns the cast votes for a record. 522 type Results struct { 523 Token string `json:"token"` 524 } 525 526 // ResultsReply is the reply to the Results command. 527 type ResultsReply struct { 528 Votes []CastVoteDetails `json:"votes"` 529 } 530 531 // VoteResult describes a vote option and the total number of votes that have 532 // been cast for this option. 533 type VoteResult struct { 534 ID string `json:"id"` // Single unique word (e.g. yes) 535 Description string `json:"description"` // Longer description of the vote 536 VoteBit uint64 `json:"votebit"` // Bits used for this option 537 Votes uint64 `json:"votes"` // Votes cast for this option 538 } 539 540 // Summary summarizes the vote params and results of a record vote. 541 type Summary struct { 542 Type VoteT `json:"type"` 543 Status VoteStatusT `json:"status"` 544 Duration uint32 `json:"duration"` // In blocks 545 StartBlockHeight uint32 `json:"startblockheight"` 546 StartBlockHash string `json:"startblockhash"` 547 EndBlockHeight uint32 `json:"endblockheight"` 548 549 // EligibleTickets is the number of tickets that are eligible to 550 // cast a vote. 551 EligibleTickets uint32 `json:"eligibletickets"` 552 553 // QuorumPercentage is the percent of eligible tickets required to 554 // vote in order to have a quorum. 555 QuorumPercentage uint32 `json:"quorumpercentage"` 556 557 // PassPercentage is the percent of cast votes required for a vote 558 // option to be considered as passing. 559 PassPercentage uint32 `json:"passpercentage"` 560 561 Results []VoteResult `json:"results"` 562 563 // BestBlock is the best block value that was used to prepare the 564 // summary. 565 BestBlock uint32 `json:"bestblock"` 566 } 567 568 const ( 569 // SummariesPageSize is the maximum number of vote summaries that 570 // can be requested at any one time. 571 // 572 // NOTE: This is DEPRECATED and will be deleted as part of the next major 573 // release. Use the API's Policy route to retrieve the routes page sizes. 574 SummariesPageSize uint32 = 5 575 ) 576 577 // Summaries requests the vote summaries for the provided record tokens. 578 type Summaries struct { 579 Tokens []string `json:"tokens"` 580 } 581 582 // SummariesReply is the reply to the Summaries command. 583 // 584 // Summaries field contains a vote summary for each of the provided tokens. 585 // The map will not contain an entry for any tokens that did not correspond 586 // to an actual record. It is the callers responsibility to ensure that a 587 // summary is returned for all provided tokens. 588 type SummariesReply struct { 589 Summaries map[string]Summary `json:"summaries"` // [token]Summary 590 } 591 592 // Submissions requests the submissions of a runoff vote. The only records 593 // that will have a submissions list are the parent records in a runoff vote. 594 // The list will contain all public runoff vote submissions, i.e. records that 595 // have linked to the parent record using the VoteMetadata LinkTo field. 596 type Submissions struct { 597 Token string `json:"token"` 598 } 599 600 // SubmissionsReply is the reply to the Submissions command. 601 type SubmissionsReply struct { 602 Submissions []string `json:"submissions"` 603 } 604 605 const ( 606 // InventoryPageSize is the maximum number of tokens that will be 607 // returned for any single status in an InventoryReply. 608 // 609 // NOTE: This is DEPRECATED and will be deleted as part of the next major 610 // release. Use the API's Policy route to retrieve the routes page sizes. 611 InventoryPageSize uint32 = 20 612 ) 613 614 // Inventory requests the tokens of public records in the inventory 615 // categorized by vote status. 616 // 617 // The status and page arguments can be provided to request a specific page of 618 // record tokens. 619 // 620 // If no status is provided then a page of tokens for all statuses will be 621 // returned. The page argument will be ignored. 622 type Inventory struct { 623 Status VoteStatusT `json:"status,omitempty"` 624 Page uint32 `json:"page,omitempty"` 625 } 626 627 // InventoryReply is the reply to the Inventory command. The returned map is a 628 // map[votestatus][]token where the votestatus key is the human readable vote 629 // status defined by the VoteStatuses array in this package. 630 // 631 // Sorted by timestamp newest to oldest: 632 // Unauthorized, Authorized 633 // 634 // Sorted by vote start block height in descending order: 635 // Started 636 // 637 // Sorted by vote end block height in descending order: 638 // Finished, Approved, Rejected 639 type InventoryReply struct { 640 Vetted map[string][]string `json:"vetted"` 641 642 // BestBlock is the best block value that was used to prepare the 643 // inventory. 644 BestBlock uint32 `json:"bestblock"` 645 } 646 647 // Proof contains an inclusion proof for the digest in the merkle root. All 648 // digests are hex encoded SHA256 digests. 649 // 650 // The ExtraData field is used by certain types of proofs to include additional 651 // data that is required to validate the proof. 652 type Proof struct { 653 Type string `json:"type"` 654 Digest string `json:"digest"` 655 MerkleRoot string `json:"merkleroot"` 656 MerklePath []string `json:"merklepath"` 657 ExtraData string `json:"extradata"` // JSON encoded 658 } 659 660 // Timestamp contains all of the data required to verify that a piece of data 661 // was timestamped onto the decred blockchain. 662 // 663 // All digests are hex encoded SHA256 digests. The merkle root can be found in 664 // the OP_RETURN of the specified DCR transaction. 665 // 666 // TxID, MerkleRoot, and Proofs will only be populated once the merkle root has 667 // been included in a DCR tx and the tx has 6 confirmations. The Data field 668 // will not be populated if the data has been censored. 669 type Timestamp struct { 670 Data string `json:"data"` // JSON encoded 671 Digest string `json:"digest"` 672 TxID string `json:"txid"` 673 MerkleRoot string `json:"merkleroot"` 674 Proofs []Proof `json:"proofs"` 675 } 676 677 const ( 678 // VoteTimestampsPageSize is the maximum number of vote timestamps 679 // that will be returned for any single request. 680 // 681 // NOTE: This is DEPRECATED and will be deleted as part of the next major 682 // release. Use the API's Policy route to retrieve the routes page sizes. 683 VoteTimestampsPageSize uint32 = 100 684 ) 685 686 // Timestamps requests the timestamps for ticket vote data. 687 // 688 // If no votes page number is provided then the vote authorization and vote 689 // details timestamps will be returned. If a votes page number is provided 690 // then the specified page of cast vote timestamps will be returned. 691 type Timestamps struct { 692 Token string `json:"token"` 693 VotesPage uint32 `json:"votespage,omitempty"` 694 } 695 696 // TimestampsReply is the reply to the Timestamps command. 697 type TimestampsReply struct { 698 // Auths contains the timestamps for vote authorizations. The data 699 // payloads will contain AuthDetails structures. 700 Auths []Timestamp `json:"auths,omitempty"` 701 702 // Details contains the timestamps for the vote details. The data 703 // payload will contain a VoteDetails structure. 704 Details *Timestamp `json:"details,omitempty"` 705 706 // Votes contains the timestamps for the cast votes. The data 707 // payloads will contain CastVoteDetails strucutures. 708 Votes []Timestamp `json:"votes,omitempty"` 709 }