github.com/deso-protocol/core@v1.2.9/lib/network.go (about) 1 package lib 2 3 import ( 4 "bytes" 5 "crypto/ecdsa" 6 "crypto/rand" 7 "encoding/binary" 8 "encoding/json" 9 "fmt" 10 "io" 11 "math" 12 "net" 13 "sort" 14 "time" 15 16 "github.com/btcsuite/btcd/btcec" 17 "github.com/btcsuite/btcd/wire" 18 merkletree "github.com/deso-protocol/go-merkle-tree" 19 "github.com/ethereum/go-ethereum/crypto/ecies" 20 21 "github.com/pkg/errors" 22 ) 23 24 // network.go defines all the basic data structures that get sent over the 25 // network and defines precisely how they are serialized and de-serialized. 26 27 // MaxMessagePayload is the maximum size alowed for a message payload. 28 const MaxMessagePayload = (1024 * 1024 * 100) // 100MB 29 30 // MaxBlockRewardDataSizeBytes is the maximum size allowed for a BLOCK_REWARD's ExtraData field. 31 var MaxBlockRewardDataSizeBytes = 250 32 33 // MaxHeadersPerMsg is the maximum numbers allowed in a GetHeaders response. 34 var MaxHeadersPerMsg = uint32(2000) 35 36 // MaxBitcoinHeadersPerMsg is the maximum number of headers Bitcoin allows in 37 // a getheaders response. It is used to determine whether a node has more headers 38 // to give us. 39 var MaxBitcoinHeadersPerMsg = uint32(2000) 40 41 // The MsgType is usually sent on the wire to indicate what type of 42 // struct is being sent in the payload part of the message. 43 type MsgType uint64 44 45 const ( 46 // ControlMessagesStart is used to indicate the ID value at which control 47 // messages start. Anything with an ID value greater than or equal to this 48 // is a control message. 49 ControlMessagesStart = 1000000 50 51 MsgTypeUnset MsgType = 0 52 // 53 // The first message a peer sends. Used to negotiate a version 54 // between the two peers. 55 MsgTypeVersion MsgType = 1 56 // 57 // Sent after a peer has both sent its version message 58 // and received its peer's version message and completed 59 // the version negotiation. 60 MsgTypeVerack MsgType = 2 61 MsgTypeHeader MsgType = 3 62 MsgTypeBlock MsgType = 4 63 MsgTypeTxn MsgType = 5 64 // MsgTypeGetHeaders is used to fetch headers from a peer. 65 MsgTypeGetHeaders MsgType = 6 66 // MsgTypeHeaderBundle contains headers from a peer. 67 MsgTypeHeaderBundle MsgType = 7 68 MsgTypePing MsgType = 8 69 MsgTypePong MsgType = 9 70 MsgTypeInv MsgType = 10 71 MsgTypeGetBlocks MsgType = 11 72 MsgTypeGetTransactions MsgType = 12 73 // MsgTypeTransactionBundle contains transactions from a peer. 74 MsgTypeTransactionBundle MsgType = 13 75 MsgTypeMempool MsgType = 14 76 // MsgTypeAddr is used by peers to share addresses of nodes they're aware about 77 // with other peers. 78 MsgTypeAddr MsgType = 15 79 // MsgTypeGetAddr is used to solicit Addr messages from peers. 80 MsgTypeGetAddr MsgType = 16 81 82 // NEXT_TAG = 18 83 84 // Below are control messages used to signal to the Server from other parts of 85 // the code but not actually sent among peers. 86 // 87 // TODO: Should probably split these out into a separate channel in the server to 88 // make things more parallelized. 89 90 MsgTypeQuit MsgType = ControlMessagesStart 91 MsgTypeNewPeer MsgType = ControlMessagesStart + 1 92 MsgTypeDonePeer MsgType = ControlMessagesStart + 2 93 MsgTypeBlockAccepted MsgType = ControlMessagesStart + 3 94 MsgTypeBitcoinManagerUpdate MsgType = ControlMessagesStart + 4 95 96 // NEXT_TAG = 7 97 ) 98 99 // IsControlMessage is used by functions to determine whether a particular message 100 // is a control message. This is useful, for example, in disallowing external Peers 101 // from manipulating our node by sending control messages of their own. 102 func IsControlMessage(msgType MsgType) bool { 103 return uint64(msgType) >= ControlMessagesStart 104 } 105 106 func (msgType MsgType) String() string { 107 switch msgType { 108 case MsgTypeUnset: 109 return "UNSET" 110 case MsgTypeVersion: 111 return "VERSION" 112 case MsgTypeVerack: 113 return "VERACK" 114 // Note that we don't usually write single block headers to the wire, 115 // preferring instead to bundle headers into a single HEADER_BUNDLE message. 116 case MsgTypeHeader: 117 return "HEADER" 118 case MsgTypeBlock: 119 return "BLOCK" 120 case MsgTypeTxn: 121 return "TXN" 122 case MsgTypeGetHeaders: 123 return "GET_HEADERS" 124 case MsgTypeHeaderBundle: 125 return "HEADER_BUNDLE" 126 case MsgTypePing: 127 return "PING" 128 case MsgTypePong: 129 return "PONG" 130 case MsgTypeInv: 131 return "INV" 132 case MsgTypeGetBlocks: 133 return "GET_BLOCKS" 134 case MsgTypeGetTransactions: 135 return "GET_TRANSACTIONS" 136 case MsgTypeTransactionBundle: 137 return "TRANSACTION_BUNDLE" 138 case MsgTypeMempool: 139 return "MEMPOOL" 140 case MsgTypeAddr: 141 return "ADDR" 142 case MsgTypeGetAddr: 143 return "GET_ADDR" 144 case MsgTypeQuit: 145 return "QUIT" 146 case MsgTypeNewPeer: 147 return "NEW_PEER" 148 case MsgTypeDonePeer: 149 return "DONE_PEER" 150 case MsgTypeBlockAccepted: 151 return "BLOCK_ACCEPTED" 152 case MsgTypeBitcoinManagerUpdate: 153 return "BITCOIN_MANAGER_UPDATE" 154 default: 155 return fmt.Sprintf("UNRECOGNIZED(%d) - make sure String() is up to date", msgType) 156 } 157 } 158 159 // DeSoMessage is the interface that a message we send on the wire must implement. 160 type DeSoMessage interface { 161 // The following methods allow one to convert a message struct into 162 // a byte slice and back. Example usage: 163 // 164 // params := &DeSoTestnetParams 165 // msgType := MsgTypeVersion 166 // byteSlice := []byte{0x00, ...} 167 // 168 // msg := NewMessage(msgType) 169 // err := msg.FromBytes(byteSlice) 170 // newByteSlice, err := msg.ToBytes(false) 171 // 172 // The data format is intended to be compact while allowing for efficient 173 // transmission over the wire and storage in a database. 174 // 175 // The preSignature field specifies whether the message should be fully 176 // serialized or whether it should be serialized in such a way that it 177 // can be signed (which involves, for example, not serializing signature 178 // fields). 179 ToBytes(preSignature bool) ([]byte, error) 180 FromBytes(data []byte) error 181 182 // Each Message has a particular type. 183 GetMsgType() MsgType 184 } 185 186 // TxnType specifies the type for a transaction message. 187 type TxnType uint8 188 189 const ( 190 TxnTypeUnset TxnType = 0 191 TxnTypeBlockReward TxnType = 1 192 TxnTypeBasicTransfer TxnType = 2 193 TxnTypeBitcoinExchange TxnType = 3 194 TxnTypePrivateMessage TxnType = 4 195 TxnTypeSubmitPost TxnType = 5 196 TxnTypeUpdateProfile TxnType = 6 197 TxnTypeUpdateBitcoinUSDExchangeRate TxnType = 8 198 TxnTypeFollow TxnType = 9 199 TxnTypeLike TxnType = 10 200 TxnTypeCreatorCoin TxnType = 11 201 TxnTypeSwapIdentity TxnType = 12 202 TxnTypeUpdateGlobalParams TxnType = 13 203 TxnTypeCreatorCoinTransfer TxnType = 14 204 TxnTypeCreateNFT TxnType = 15 205 TxnTypeUpdateNFT TxnType = 16 206 TxnTypeAcceptNFTBid TxnType = 17 207 TxnTypeNFTBid TxnType = 18 208 TxnTypeNFTTransfer TxnType = 19 209 TxnTypeAcceptNFTTransfer TxnType = 20 210 TxnTypeBurnNFT TxnType = 21 211 TxnTypeAuthorizeDerivedKey TxnType = 22 212 213 // NEXT_ID = 23 214 ) 215 216 type TxnString string 217 218 const ( 219 TxnStringUnset TxnString = "UNSET" 220 TxnStringBlockReward TxnString = "BLOCK_REWARD" 221 TxnStringBasicTransfer TxnString = "BASIC_TRANSFER" 222 TxnStringBitcoinExchange TxnString = "BITCOIN_EXCHANGE" 223 TxnStringPrivateMessage TxnString = "PRIVATE_MESSAGE" 224 TxnStringSubmitPost TxnString = "SUBMIT_POST" 225 TxnStringUpdateProfile TxnString = "UPDATE_PROFILE" 226 TxnStringUpdateBitcoinUSDExchangeRate TxnString = "UPDATE_BITCOIN_USD_EXCHANGE_RATE" 227 TxnStringFollow TxnString = "FOLLOW" 228 TxnStringLike TxnString = "LIKE" 229 TxnStringCreatorCoin TxnString = "CREATOR_COIN" 230 TxnStringSwapIdentity TxnString = "SWAP_IDENTITY" 231 TxnStringUpdateGlobalParams TxnString = "UPDATE_GLOBAL_PARAMS" 232 TxnStringCreatorCoinTransfer TxnString = "CREATOR_COIN_TRANSFER" 233 TxnStringCreateNFT TxnString = "CREATE_NFT" 234 TxnStringUpdateNFT TxnString = "UPDATE_NFT" 235 TxnStringAcceptNFTBid TxnString = "ACCEPT_NFT_BID" 236 TxnStringNFTBid TxnString = "NFT_BID" 237 TxnStringNFTTransfer TxnString = "NFT_TRANSFER" 238 TxnStringAcceptNFTTransfer TxnString = "ACCEPT_NFT_TRANSFER" 239 TxnStringBurnNFT TxnString = "BURN_NFT" 240 TxnStringAuthorizeDerivedKey TxnString = "AUTHORIZE_DERIVED_KEY" 241 TxnStringUndefined TxnString = "TXN_UNDEFINED" 242 ) 243 244 var ( 245 AllTxnTypes = []TxnType{ 246 TxnTypeUnset, TxnTypeBlockReward, TxnTypeBasicTransfer, TxnTypeBitcoinExchange, TxnTypePrivateMessage, 247 TxnTypeSubmitPost, TxnTypeUpdateProfile, TxnTypeUpdateBitcoinUSDExchangeRate, TxnTypeFollow, TxnTypeLike, 248 TxnTypeCreatorCoin, TxnTypeSwapIdentity, TxnTypeUpdateGlobalParams, TxnTypeCreatorCoinTransfer, 249 TxnTypeCreateNFT, TxnTypeUpdateNFT, TxnTypeAcceptNFTBid, TxnTypeNFTBid, TxnTypeNFTTransfer, 250 TxnTypeAcceptNFTTransfer, TxnTypeBurnNFT, TxnTypeAuthorizeDerivedKey, 251 } 252 AllTxnString = []TxnString{ 253 TxnStringUnset, TxnStringBlockReward, TxnStringBasicTransfer, TxnStringBitcoinExchange, TxnStringPrivateMessage, 254 TxnStringSubmitPost, TxnStringUpdateProfile, TxnStringUpdateBitcoinUSDExchangeRate, TxnStringFollow, TxnStringLike, 255 TxnStringCreatorCoin, TxnStringSwapIdentity, TxnStringUpdateGlobalParams, TxnStringCreatorCoinTransfer, 256 TxnStringCreateNFT, TxnStringUpdateNFT, TxnStringAcceptNFTBid, TxnStringNFTBid, TxnStringNFTTransfer, 257 TxnStringAcceptNFTTransfer, TxnStringBurnNFT, TxnStringAuthorizeDerivedKey, 258 } 259 ) 260 261 func (txnType TxnType) String() string { 262 txnString := txnType.GetTxnString() 263 if txnString == TxnStringUndefined { 264 return fmt.Sprintf("UNRECOGNIZED(%d) - make sure GetTxnString() is up to date", txnType) 265 } 266 return string(txnString) 267 } 268 269 func (txnType TxnType) GetTxnString() TxnString { 270 switch txnType { 271 case TxnTypeUnset: 272 return TxnStringUnset 273 case TxnTypeBlockReward: 274 return TxnStringBlockReward 275 case TxnTypeBasicTransfer: 276 return TxnStringBasicTransfer 277 case TxnTypeBitcoinExchange: 278 return TxnStringBitcoinExchange 279 case TxnTypePrivateMessage: 280 return TxnStringPrivateMessage 281 case TxnTypeSubmitPost: 282 return TxnStringSubmitPost 283 case TxnTypeUpdateProfile: 284 return TxnStringUpdateProfile 285 case TxnTypeUpdateBitcoinUSDExchangeRate: 286 return TxnStringUpdateBitcoinUSDExchangeRate 287 case TxnTypeFollow: 288 return TxnStringFollow 289 case TxnTypeLike: 290 return TxnStringLike 291 case TxnTypeCreatorCoin: 292 return TxnStringCreatorCoin 293 case TxnTypeCreatorCoinTransfer: 294 return TxnStringCreatorCoinTransfer 295 case TxnTypeSwapIdentity: 296 return TxnStringSwapIdentity 297 case TxnTypeUpdateGlobalParams: 298 return TxnStringUpdateGlobalParams 299 case TxnTypeCreateNFT: 300 return TxnStringCreateNFT 301 case TxnTypeUpdateNFT: 302 return TxnStringUpdateNFT 303 case TxnTypeAcceptNFTBid: 304 return TxnStringAcceptNFTBid 305 case TxnTypeNFTBid: 306 return TxnStringNFTBid 307 case TxnTypeNFTTransfer: 308 return TxnStringNFTTransfer 309 case TxnTypeAcceptNFTTransfer: 310 return TxnStringAcceptNFTTransfer 311 case TxnTypeBurnNFT: 312 return TxnStringBurnNFT 313 case TxnTypeAuthorizeDerivedKey: 314 return TxnStringAuthorizeDerivedKey 315 316 default: 317 return TxnStringUndefined 318 } 319 } 320 321 func GetTxnTypeFromString(txnString TxnString) TxnType { 322 switch txnString { 323 case TxnStringUnset: 324 return TxnTypeUnset 325 case TxnStringBlockReward: 326 return TxnTypeBlockReward 327 case TxnStringBasicTransfer: 328 return TxnTypeBasicTransfer 329 case TxnStringBitcoinExchange: 330 return TxnTypeBitcoinExchange 331 case TxnStringPrivateMessage: 332 return TxnTypePrivateMessage 333 case TxnStringSubmitPost: 334 return TxnTypeSubmitPost 335 case TxnStringUpdateProfile: 336 return TxnTypeUpdateProfile 337 case TxnStringUpdateBitcoinUSDExchangeRate: 338 return TxnTypeUpdateBitcoinUSDExchangeRate 339 case TxnStringFollow: 340 return TxnTypeFollow 341 case TxnStringLike: 342 return TxnTypeLike 343 case TxnStringCreatorCoin: 344 return TxnTypeCreatorCoin 345 case TxnStringCreatorCoinTransfer: 346 return TxnTypeCreatorCoinTransfer 347 case TxnStringSwapIdentity: 348 return TxnTypeSwapIdentity 349 case TxnStringUpdateGlobalParams: 350 return TxnTypeUpdateGlobalParams 351 case TxnStringCreateNFT: 352 return TxnTypeCreateNFT 353 case TxnStringUpdateNFT: 354 return TxnTypeUpdateNFT 355 case TxnStringAcceptNFTBid: 356 return TxnTypeAcceptNFTBid 357 case TxnStringNFTBid: 358 return TxnTypeNFTBid 359 case TxnStringNFTTransfer: 360 return TxnTypeNFTTransfer 361 case TxnStringAcceptNFTTransfer: 362 return TxnTypeNFTTransfer 363 case TxnStringBurnNFT: 364 return TxnTypeBurnNFT 365 case TxnStringAuthorizeDerivedKey: 366 return TxnTypeAuthorizeDerivedKey 367 368 default: 369 // TxnTypeUnset means we couldn't find a matching txn type 370 return TxnTypeUnset 371 } 372 } 373 374 type DeSoTxnMetadata interface { 375 ToBytes(preSignature bool) ([]byte, error) 376 FromBytes(data []byte) error 377 New() DeSoTxnMetadata 378 GetTxnType() TxnType 379 } 380 381 func NewTxnMetadata(txType TxnType) (DeSoTxnMetadata, error) { 382 switch txType { 383 case TxnTypeUnset: 384 return nil, fmt.Errorf("NewTxnMetadata: UNSET TxnType: %v", TxnTypeUnset) 385 case TxnTypeBlockReward: 386 return (&BlockRewardMetadataa{}).New(), nil 387 case TxnTypeBasicTransfer: 388 return (&BasicTransferMetadata{}).New(), nil 389 case TxnTypeBitcoinExchange: 390 return (&BitcoinExchangeMetadata{}).New(), nil 391 case TxnTypePrivateMessage: 392 return (&PrivateMessageMetadata{}).New(), nil 393 case TxnTypeSubmitPost: 394 return (&SubmitPostMetadata{}).New(), nil 395 case TxnTypeUpdateProfile: 396 return (&UpdateProfileMetadata{}).New(), nil 397 case TxnTypeUpdateBitcoinUSDExchangeRate: 398 return (&UpdateBitcoinUSDExchangeRateMetadataa{}).New(), nil 399 case TxnTypeFollow: 400 return (&FollowMetadata{}).New(), nil 401 case TxnTypeLike: 402 return (&LikeMetadata{}).New(), nil 403 case TxnTypeCreatorCoin: 404 return (&CreatorCoinMetadataa{}).New(), nil 405 case TxnTypeCreatorCoinTransfer: 406 return (&CreatorCoinTransferMetadataa{}).New(), nil 407 case TxnTypeSwapIdentity: 408 return (&SwapIdentityMetadataa{}).New(), nil 409 case TxnTypeUpdateGlobalParams: 410 return (&UpdateGlobalParamsMetadata{}).New(), nil 411 case TxnTypeCreateNFT: 412 return (&CreateNFTMetadata{}).New(), nil 413 case TxnTypeUpdateNFT: 414 return (&UpdateNFTMetadata{}).New(), nil 415 case TxnTypeAcceptNFTBid: 416 return (&AcceptNFTBidMetadata{}).New(), nil 417 case TxnTypeNFTBid: 418 return (&NFTBidMetadata{}).New(), nil 419 case TxnTypeNFTTransfer: 420 return (&NFTTransferMetadata{}).New(), nil 421 case TxnTypeAcceptNFTTransfer: 422 return (&AcceptNFTTransferMetadata{}).New(), nil 423 case TxnTypeBurnNFT: 424 return (&BurnNFTMetadata{}).New(), nil 425 case TxnTypeAuthorizeDerivedKey: 426 return (&AuthorizeDerivedKeyMetadata{}).New(), nil 427 428 default: 429 return nil, fmt.Errorf("NewTxnMetadata: Unrecognized TxnType: %v; make sure you add the new type of transaction to NewTxnMetadata", txType) 430 } 431 } 432 433 // WriteMessage takes an io.Writer and serializes and writes the specified message 434 // to it. Returns an error if the message is malformed or invalid for any reason. 435 // Otherwise returns the payload that was written sans the header. 436 func WriteMessage(ww io.Writer, msg DeSoMessage, networkType NetworkType) ([]byte, error) { 437 hdr := []byte{} 438 439 // Add the network as a uvarint. 440 hdr = append(hdr, UintToBuf(uint64(networkType))...) 441 442 // Add the MsgType as a uvarint. 443 hdr = append(hdr, UintToBuf(uint64(msg.GetMsgType()))...) 444 445 // Compute the payload we're going to write but don't add it 446 // yet. 447 payload, err := msg.ToBytes(false) 448 if err != nil { 449 return nil, errors.Wrap(err, "WriteMessage: Failed to convert message to bytes") 450 } 451 452 // Check that the length of the payload does not exceed the maximum 453 // allowed limit. 454 if len(payload) > MaxMessagePayload { 455 return nil, fmt.Errorf("WriteMessage: Payload size (%d) bytes is too "+ 456 "large. Should be no larger than (%d) bytes", len(payload), MaxMessagePayload) 457 } 458 459 // Add an eight-byte checksum of the payload. Note that although 460 // we generally communicate over TCP, it's not a great idea to rely on the 461 // checksum it uses since its guarantees are relatively weak. 462 // https://www.evanjones.ca/tcp-checksums.html 463 hash := Sha256DoubleHash(payload) 464 hdr = append(hdr, hash[:8]...) 465 466 // Add the payload length as a uvarint. 467 hdr = append(hdr, UintToBuf(uint64(len(payload)))...) 468 469 // Write the message header. 470 _, err = ww.Write(hdr) 471 if err != nil { 472 return nil, errors.Wrap(err, "WriteMessage: Failed to write header") 473 } 474 475 // Write the payload. 476 _, err = ww.Write(payload) 477 if err != nil { 478 return nil, errors.Wrap(err, "WriteMessage: Failed to write payload") 479 } 480 return payload, nil 481 } 482 483 // ReadMessage takes an io.Reader and de-serializes a single message from it. 484 // Returns an error if the message is malformed or invalid for any reason. Otherwise 485 // returns a formed message object and the raw byte payload from which it was 486 // derived. 487 func ReadMessage(rr io.Reader, networkType NetworkType) (DeSoMessage, []byte, error) { 488 // Read the network as a uvarint. 489 inNetworkType, err := ReadUvarint(rr) 490 if err != nil { 491 return nil, nil, errors.Wrapf(err, "ReadMessage: Problem decoding NetworkType") 492 } 493 if NetworkType(inNetworkType) != networkType { 494 return nil, nil, fmt.Errorf("ReadMessage: Incorrect network type (%s) expected (%s)", NetworkType(inNetworkType), networkType) 495 } 496 497 // Read the MsgType as a uvarint. 498 inMsgType, err := ReadUvarint(rr) 499 if err != nil { 500 return nil, nil, errors.Wrap(err, "ReadMessage: Could not read MsgType") 501 } 502 503 // Create a new message object based on the type. 504 retMsg := NewMessage(MsgType(inMsgType)) 505 if retMsg == nil { 506 return nil, nil, fmt.Errorf("ReadMessage: Unknown message type (%s)", MsgType(inMsgType)) 507 } 508 509 // Read the payload checksum. 510 checksum := make([]byte, 8) 511 _, err = io.ReadFull(rr, checksum) 512 if err != nil { 513 return nil, nil, fmt.Errorf("ReadMessage: Error reading checksum for messate type (%s)", MsgType(inMsgType)) 514 } 515 516 // Read the length of the payload. 517 payloadLength, err := ReadUvarint(rr) 518 if err != nil { 519 return nil, nil, errors.Wrapf(err, "ReadMessage: Could not read payload length for message type (%s)", MsgType(inMsgType)) 520 } 521 522 // Check that the payload length does not exceed the maximum value allowed. 523 // This prevents adversarial machines from overflowing our 524 if payloadLength > MaxMessagePayload { 525 return nil, nil, fmt.Errorf("ReadMessage: Payload size (%d) bytes is too "+ 526 "large. Should be no larger than (%d) bytes", payloadLength, MaxMessagePayload) 527 } 528 529 // Read the payload. 530 payload := make([]byte, payloadLength) 531 _, err = io.ReadFull(rr, payload) 532 if err != nil { 533 return nil, nil, errors.Wrapf(err, "ReadMessage: Could not read payload for message type (%s)", MsgType(inMsgType)) 534 } 535 536 // Check the payload checksum. 537 hash := Sha256DoubleHash(payload) 538 if !bytes.Equal(hash[:8], checksum) { 539 return nil, nil, fmt.Errorf("ReadMessage: Payload checksum computed "+ 540 "(%#v) does not match payload checksum in header: (%#v)", hash[:8], checksum) 541 } 542 543 // Now we have the payload, initialize the message. 544 err = retMsg.FromBytes(payload) 545 if err != nil { 546 return nil, nil, errors.Wrapf(err, "ReadMessage: Problem parsing "+ 547 "message payload into message object for message type (%s)", MsgType(inMsgType)) 548 } 549 550 return retMsg, payload, nil 551 } 552 553 func NewMessage(msgType MsgType) DeSoMessage { 554 switch msgType { 555 case MsgTypeVersion: 556 { 557 return &MsgDeSoVersion{} 558 } 559 case MsgTypeVerack: 560 { 561 return &MsgDeSoVerack{} 562 } 563 case MsgTypeHeader: 564 { 565 return &MsgDeSoHeader{ 566 PrevBlockHash: &BlockHash{}, 567 TransactionMerkleRoot: &BlockHash{}, 568 } 569 } 570 case MsgTypeBlock: 571 { 572 return &MsgDeSoBlock{ 573 Header: NewMessage(MsgTypeHeader).(*MsgDeSoHeader), 574 } 575 } 576 case MsgTypeTxn: 577 { 578 return &MsgDeSoTxn{} 579 } 580 case MsgTypePing: 581 { 582 return &MsgDeSoPing{} 583 } 584 case MsgTypePong: 585 { 586 return &MsgDeSoPong{} 587 } 588 case MsgTypeInv: 589 { 590 return &MsgDeSoInv{} 591 } 592 case MsgTypeGetBlocks: 593 { 594 return &MsgDeSoGetBlocks{} 595 } 596 case MsgTypeGetTransactions: 597 { 598 return &MsgDeSoGetTransactions{} 599 } 600 case MsgTypeTransactionBundle: 601 { 602 return &MsgDeSoTransactionBundle{} 603 } 604 case MsgTypeMempool: 605 { 606 return &MsgDeSoMempool{} 607 } 608 case MsgTypeGetHeaders: 609 { 610 return &MsgDeSoGetHeaders{} 611 } 612 case MsgTypeHeaderBundle: 613 { 614 return &MsgDeSoHeaderBundle{} 615 } 616 case MsgTypeAddr: 617 { 618 return &MsgDeSoAddr{} 619 } 620 case MsgTypeGetAddr: 621 { 622 return &MsgDeSoGetAddr{} 623 } 624 default: 625 { 626 return nil 627 } 628 } 629 } 630 631 // ================================================================== 632 // Control Messages 633 // ================================================================== 634 635 type MsgDeSoQuit struct { 636 } 637 638 func (msg *MsgDeSoQuit) GetMsgType() MsgType { 639 return MsgTypeQuit 640 } 641 642 func (msg *MsgDeSoQuit) ToBytes(preSignature bool) ([]byte, error) { 643 return nil, fmt.Errorf("MsgDeSoQuit.ToBytes not implemented") 644 } 645 646 func (msg *MsgDeSoQuit) FromBytes(data []byte) error { 647 return fmt.Errorf("MsgDeSoQuit.FromBytes not implemented") 648 } 649 650 type MsgDeSoNewPeer struct { 651 } 652 653 func (msg *MsgDeSoNewPeer) GetMsgType() MsgType { 654 return MsgTypeNewPeer 655 } 656 657 func (msg *MsgDeSoNewPeer) ToBytes(preSignature bool) ([]byte, error) { 658 return nil, fmt.Errorf("MsgDeSoNewPeer.ToBytes: Not implemented") 659 } 660 661 func (msg *MsgDeSoNewPeer) FromBytes(data []byte) error { 662 return fmt.Errorf("MsgDeSoNewPeer.FromBytes not implemented") 663 } 664 665 type MsgDeSoDonePeer struct { 666 } 667 668 func (msg *MsgDeSoDonePeer) GetMsgType() MsgType { 669 return MsgTypeDonePeer 670 } 671 672 func (msg *MsgDeSoDonePeer) ToBytes(preSignature bool) ([]byte, error) { 673 return nil, fmt.Errorf("MsgDeSoDonePeer.ToBytes: Not implemented") 674 } 675 676 func (msg *MsgDeSoDonePeer) FromBytes(data []byte) error { 677 return fmt.Errorf("MsgDeSoDonePeer.FromBytes not implemented") 678 } 679 680 type MsgDeSoBitcoinManagerUpdate struct { 681 // Keep it simple for now. A BitcoinManagerUpdate just signals that 682 // the BitcoinManager has added at least one block or done a reorg. 683 // No serialization because we don't want this sent on the wire ever. 684 TransactionsFound []*MsgDeSoTxn 685 } 686 687 func (msg *MsgDeSoBitcoinManagerUpdate) GetMsgType() MsgType { 688 return MsgTypeBitcoinManagerUpdate 689 } 690 691 func (msg *MsgDeSoBitcoinManagerUpdate) ToBytes(preSignature bool) ([]byte, error) { 692 return nil, fmt.Errorf("MsgDeSoBitcoinManagerUpdate.ToBytes: Not implemented") 693 } 694 695 func (msg *MsgDeSoBitcoinManagerUpdate) FromBytes(data []byte) error { 696 return fmt.Errorf("MsgDeSoBitcoinManagerUpdate.FromBytes not implemented") 697 } 698 699 // ================================================================== 700 // GET_HEADERS message 701 // ================================================================== 702 703 type MsgDeSoGetHeaders struct { 704 StopHash *BlockHash 705 BlockLocator []*BlockHash 706 } 707 708 func (msg *MsgDeSoGetHeaders) GetMsgType() MsgType { 709 return MsgTypeGetHeaders 710 } 711 712 func (msg *MsgDeSoGetHeaders) ToBytes(preSignature bool) ([]byte, error) { 713 data := []byte{} 714 715 // Encode the StopHash first. 716 data = append(data, msg.StopHash[:]...) 717 718 // Encode the number of hashes in the BlockLocator. 719 data = append(data, UintToBuf(uint64(len(msg.BlockLocator)))...) 720 721 // Encode all of the hashes in the BlockLocator. 722 for _, hash := range msg.BlockLocator { 723 data = append(data, hash[:]...) 724 } 725 726 return data, nil 727 } 728 729 func (msg *MsgDeSoGetHeaders) FromBytes(data []byte) error { 730 rr := bytes.NewReader(data) 731 retGetHeaders := NewMessage(MsgTypeGetHeaders).(*MsgDeSoGetHeaders) 732 733 // StopHash 734 stopHash := BlockHash{} 735 _, err := io.ReadFull(rr, stopHash[:]) 736 if err != nil { 737 return errors.Wrapf(err, "MsgDeSoGetHeaders.FromBytes: Problem decoding StopHash") 738 } 739 retGetHeaders.StopHash = &stopHash 740 741 // Number of hashes in block locator. 742 numHeaders, err := ReadUvarint(rr) 743 if err != nil { 744 return fmt.Errorf("MsgDeSoGetHeaders.FromBytes: %v", err) 745 } 746 747 for ii := uint64(0); ii < numHeaders; ii++ { 748 currentHeader := BlockHash{} 749 _, err := io.ReadFull(rr, currentHeader[:]) 750 if err != nil { 751 return errors.Wrapf(err, "MsgDeSoGetHeaders.FromBytes: Problem decoding header hash") 752 } 753 754 retGetHeaders.BlockLocator = append(retGetHeaders.BlockLocator, ¤tHeader) 755 } 756 757 *msg = *retGetHeaders 758 return nil 759 } 760 761 func (msg *MsgDeSoGetHeaders) String() string { 762 return fmt.Sprintf("StopHash: %v Locator: %v", 763 msg.StopHash, msg.BlockLocator) 764 } 765 766 // ================================================================== 767 // HEADER_BUNDLE message 768 // ================================================================== 769 770 type MsgDeSoHeaderBundle struct { 771 Headers []*MsgDeSoHeader 772 TipHash *BlockHash 773 TipHeight uint32 774 } 775 776 func (msg *MsgDeSoHeaderBundle) GetMsgType() MsgType { 777 return MsgTypeHeaderBundle 778 } 779 780 func (msg *MsgDeSoHeaderBundle) ToBytes(preSignature bool) ([]byte, error) { 781 data := []byte{} 782 783 // Encode the number of headers in the bundle. 784 data = append(data, UintToBuf(uint64(len(msg.Headers)))...) 785 786 // Encode all the headers. 787 for _, header := range msg.Headers { 788 headerBytes, err := header.ToBytes(preSignature) 789 if err != nil { 790 return nil, errors.Wrapf(err, "MsgDeSoHeaderBundle.ToBytes: Problem encoding header") 791 } 792 data = append(data, headerBytes...) 793 } 794 795 // Encode the tip hash. 796 data = append(data, msg.TipHash[:]...) 797 798 // Encode the tip height. 799 data = append(data, UintToBuf(uint64(msg.TipHeight))...) 800 801 return data, nil 802 } 803 804 func (msg *MsgDeSoHeaderBundle) FromBytes(data []byte) error { 805 rr := bytes.NewReader(data) 806 retBundle := NewMessage(MsgTypeHeaderBundle).(*MsgDeSoHeaderBundle) 807 808 // Read in the number of headers in the bundle. 809 numHeaders, err := ReadUvarint(rr) 810 if err != nil { 811 return errors.Wrapf(err, "MsgDeSoHeaderBundle.FromBytes: Problem decoding number of header") 812 } 813 814 // Read in all of the headers. 815 for ii := uint64(0); ii < numHeaders; ii++ { 816 retHeader, err := DecodeHeader(rr) 817 if err != nil { 818 return errors.Wrapf(err, "MsgDeSoHeader.FromBytes: ") 819 } 820 821 retBundle.Headers = append(retBundle.Headers, retHeader) 822 } 823 824 // Read in the tip hash. 825 retBundle.TipHash = &BlockHash{} 826 _, err = io.ReadFull(rr, retBundle.TipHash[:]) 827 if err != nil { 828 return errors.Wrapf(err, "MsgDeSoHeaderBundle.FromBytes:: Error reading TipHash: ") 829 } 830 831 // Read in the tip height. 832 tipHeight, err := ReadUvarint(rr) 833 if err != nil || tipHeight > math.MaxUint32 { 834 return fmt.Errorf("MsgDeSoHeaderBundle.FromBytes: %v", err) 835 } 836 retBundle.TipHeight = uint32(tipHeight) 837 838 *msg = *retBundle 839 return nil 840 } 841 842 func (msg *MsgDeSoHeaderBundle) String() string { 843 return fmt.Sprintf("Num Headers: %v, Tip Height: %v, Tip Hash: %v, Headers: %v", len(msg.Headers), msg.TipHeight, msg.TipHash, msg.Headers) 844 } 845 846 // ================================================================== 847 // GetBlocks Messages 848 // ================================================================== 849 850 type MsgDeSoGetBlocks struct { 851 HashList []*BlockHash 852 } 853 854 func (msg *MsgDeSoGetBlocks) GetMsgType() MsgType { 855 return MsgTypeGetBlocks 856 } 857 858 func (msg *MsgDeSoGetBlocks) ToBytes(preSignature bool) ([]byte, error) { 859 data := []byte{} 860 861 if len(msg.HashList) > MaxBlocksInFlight { 862 return nil, fmt.Errorf("MsgDeSoGetBlocks.ToBytes: Blocks requested %d "+ 863 "exceeds MaxBlocksInFlight %d", len(msg.HashList), MaxBlocksInFlight) 864 } 865 866 // Encode the number of hashes. 867 data = append(data, UintToBuf(uint64(len(msg.HashList)))...) 868 // Encode each hash. 869 for _, hash := range msg.HashList { 870 data = append(data, hash[:]...) 871 } 872 873 return data, nil 874 } 875 876 func (msg *MsgDeSoGetBlocks) FromBytes(data []byte) error { 877 rr := bytes.NewReader(data) 878 879 // Parse the nmber of block hashes. 880 numHashes, err := ReadUvarint(rr) 881 if err != nil { 882 return errors.Wrapf(err, "MsgDeSoGetBlocks.FromBytes: Problem "+ 883 "reading number of block hashes requested") 884 } 885 if numHashes > MaxBlocksInFlight { 886 return fmt.Errorf("MsgDeSoGetBlocks.FromBytes: HashList length (%d) "+ 887 "exceeds maximum allowed (%d)", numHashes, MaxBlocksInFlight) 888 } 889 890 // Read in all the hashes. 891 hashList := []*BlockHash{} 892 for ii := uint64(0); ii < numHashes; ii++ { 893 newHash := BlockHash{} 894 895 _, err = io.ReadFull(rr, newHash[:]) 896 if err != nil { 897 return errors.Wrapf(err, "MsgDeSoGetBlocks.FromBytes:: Error reading Hash: ") 898 } 899 hashList = append(hashList, &newHash) 900 } 901 902 *msg = MsgDeSoGetBlocks{ 903 HashList: hashList, 904 } 905 return nil 906 } 907 908 func (msg *MsgDeSoGetBlocks) String() string { 909 return fmt.Sprintf("%v", msg.HashList) 910 } 911 912 // DeSoBodySchema Within a post, the body typically has a particular 913 // schema defined below. 914 type DeSoBodySchema struct { 915 Body string `json:",omitempty"` 916 ImageURLs []string `json:",omitempty"` 917 VideoURLs []string `json:",omitempty"` 918 } 919 920 // ================================================================== 921 // GetTransactions Messages 922 // ================================================================== 923 924 type MsgDeSoGetTransactions struct { 925 HashList []*BlockHash 926 } 927 928 func (msg *MsgDeSoGetTransactions) GetMsgType() MsgType { 929 return MsgTypeGetTransactions 930 } 931 932 func (msg *MsgDeSoGetTransactions) ToBytes(preSignature bool) ([]byte, error) { 933 data := []byte{} 934 935 // Encode the number of hashes. 936 data = append(data, UintToBuf(uint64(len(msg.HashList)))...) 937 // Encode each hash. 938 for _, hash := range msg.HashList { 939 data = append(data, hash[:]...) 940 } 941 942 return data, nil 943 } 944 945 func (msg *MsgDeSoGetTransactions) FromBytes(data []byte) error { 946 rr := bytes.NewReader(data) 947 948 // Parse the nmber of block hashes. 949 numHashes, err := ReadUvarint(rr) 950 if err != nil { 951 return errors.Wrapf(err, "MsgDeSoGetTransactions.FromBytes: Problem "+ 952 "reading number of transaction hashes requested") 953 } 954 955 // Read in all the hashes. 956 hashList := []*BlockHash{} 957 for ii := uint64(0); ii < numHashes; ii++ { 958 newHash := BlockHash{} 959 960 _, err = io.ReadFull(rr, newHash[:]) 961 if err != nil { 962 return errors.Wrapf(err, "MsgDeSoGetTransactions.FromBytes: Error reading Hash: ") 963 } 964 hashList = append(hashList, &newHash) 965 } 966 967 *msg = MsgDeSoGetTransactions{ 968 HashList: hashList, 969 } 970 return nil 971 } 972 973 func (msg *MsgDeSoGetTransactions) String() string { 974 return fmt.Sprintf("Num hashes: %v, HashList: %v", len(msg.HashList), msg.HashList) 975 } 976 977 // ================================================================== 978 // TransactionBundle message 979 // ================================================================== 980 981 type MsgDeSoTransactionBundle struct { 982 Transactions []*MsgDeSoTxn 983 } 984 985 func (msg *MsgDeSoTransactionBundle) GetMsgType() MsgType { 986 return MsgTypeTransactionBundle 987 } 988 989 func (msg *MsgDeSoTransactionBundle) ToBytes(preSignature bool) ([]byte, error) { 990 data := []byte{} 991 992 // Encode the number of transactions in the bundle. 993 data = append(data, UintToBuf(uint64(len(msg.Transactions)))...) 994 995 // Encode all the transactions. 996 for _, transaction := range msg.Transactions { 997 transactionBytes, err := transaction.ToBytes(preSignature) 998 if err != nil { 999 return nil, errors.Wrapf(err, "MsgDeSoTransactionBundle.ToBytes: Problem encoding transaction") 1000 } 1001 data = append(data, transactionBytes...) 1002 } 1003 1004 return data, nil 1005 } 1006 1007 func (msg *MsgDeSoTransactionBundle) FromBytes(data []byte) error { 1008 rr := bytes.NewReader(data) 1009 retBundle := NewMessage(MsgTypeTransactionBundle).(*MsgDeSoTransactionBundle) 1010 1011 // Read in the number of transactions in the bundle. 1012 numTransactions, err := ReadUvarint(rr) 1013 if err != nil { 1014 return errors.Wrapf(err, "MsgDeSoTransactionBundle.FromBytes: Problem decoding number of transaction") 1015 } 1016 1017 // Read in all of the transactions. 1018 for ii := uint64(0); ii < numTransactions; ii++ { 1019 retTransaction, err := _readTransaction(rr) 1020 if err != nil { 1021 return errors.Wrapf(err, "MsgDeSoTransaction.FromBytes: ") 1022 } 1023 1024 retBundle.Transactions = append(retBundle.Transactions, retTransaction) 1025 } 1026 1027 *msg = *retBundle 1028 return nil 1029 } 1030 1031 func (msg *MsgDeSoTransactionBundle) String() string { 1032 return fmt.Sprintf("Num txns: %v, Txns: %v", len(msg.Transactions), msg.Transactions) 1033 } 1034 1035 // ================================================================== 1036 // Mempool Messages 1037 // ================================================================== 1038 1039 type MsgDeSoMempool struct { 1040 } 1041 1042 func (msg *MsgDeSoMempool) GetMsgType() MsgType { 1043 return MsgTypeMempool 1044 } 1045 1046 func (msg *MsgDeSoMempool) ToBytes(preSignature bool) ([]byte, error) { 1047 // A mempool message is just empty. 1048 return []byte{}, nil 1049 } 1050 1051 func (msg *MsgDeSoMempool) FromBytes(data []byte) error { 1052 // A mempool message is just empty. 1053 return nil 1054 } 1055 1056 func (msg *MsgDeSoMempool) String() string { 1057 return fmt.Sprintf("%v", msg.GetMsgType()) 1058 } 1059 1060 // ================================================================== 1061 // INV Messages 1062 // ================================================================== 1063 1064 const ( 1065 // MaxBlocksInFlight is the maximum number of blocks that can be requested 1066 // from a peer. 1067 MaxBlocksInFlight = 250 1068 ) 1069 1070 // InvType represents the allowed types of inventory vectors. See InvVect. 1071 type InvType uint32 1072 1073 // These constants define the various supported inventory vector types. 1074 const ( 1075 InvTypeTx InvType = 0 1076 InvTypeBlock InvType = 1 1077 ) 1078 1079 // Map of service flags back to their constant names for pretty printing. 1080 var ivStrings = map[InvType]string{ 1081 InvTypeTx: "TX_INV", 1082 InvTypeBlock: "BLOCK_INV", 1083 } 1084 1085 // String returns the InvType in human-readable form. 1086 func (invtype InvType) String() string { 1087 if s, ok := ivStrings[invtype]; ok { 1088 return s 1089 } 1090 1091 return fmt.Sprintf("Unknown InvType (%d)", uint32(invtype)) 1092 } 1093 1094 // InvVect defines an inventory vector which is used to describe data, 1095 // as specified by the Type field, that a peer wants, has, or does not have to 1096 // another peer. 1097 type InvVect struct { 1098 Type InvType // Type of data 1099 Hash BlockHash // Hash of the data 1100 } 1101 1102 func (invVect *InvVect) String() string { 1103 return fmt.Sprintf("Type: %v, Hash: %v", invVect.Type, &(invVect.Hash)) 1104 } 1105 1106 type MsgDeSoInv struct { 1107 InvList []*InvVect 1108 // IsSyncResponse indicates that the inv was sent in response to a sync message. 1109 // This indicates that the node shouldn't relay it to peers because they likely 1110 // already have it. 1111 IsSyncResponse bool 1112 } 1113 1114 func (msg *MsgDeSoInv) GetMsgType() MsgType { 1115 return MsgTypeInv 1116 } 1117 1118 func _invListToBytes(invList []*InvVect) ([]byte, error) { 1119 data := []byte{} 1120 1121 // Encode the number of inventory vectors. 1122 data = append(data, UintToBuf(uint64(len(invList)))...) 1123 1124 // Encode each inventory vector subsequent. 1125 for _, invVect := range invList { 1126 data = append(data, UintToBuf(uint64(invVect.Type))...) 1127 data = append(data, invVect.Hash[:]...) 1128 } 1129 1130 return data, nil 1131 } 1132 1133 func _readInvList(rr io.Reader) ([]*InvVect, error) { 1134 invList := []*InvVect{} 1135 1136 // Parse the number of inventory vectors in the message and make sure it doesn't 1137 // exceed the limit. 1138 numInvVects, err := ReadUvarint(rr) 1139 if err != nil { 1140 return nil, errors.Wrapf(err, "_readInvList: Problem reading number of InvVects") 1141 } 1142 1143 // Now parse each individual InvVect. 1144 for ii := uint64(0); ii < numInvVects; ii++ { 1145 // Parse the type field, which was encoded as a varint. 1146 typeUint, err := ReadUvarint(rr) 1147 if err != nil { 1148 return nil, errors.Wrapf(err, "_readInvList: Problem parsing Type for InvVect") 1149 } 1150 if typeUint > math.MaxUint32 { 1151 return nil, fmt.Errorf("_readInvList: Type field exceeds maximum value sanity check (%f) vs (%f)", float64(typeUint), float64(math.MaxUint32)) 1152 } 1153 1154 // Read the Hash of the InvVect. 1155 invHash := BlockHash{} 1156 _, err = io.ReadFull(rr, invHash[:]) 1157 if err != nil { 1158 return nil, errors.Wrapf(err, "_readInvList:: Error reading Hash for InvVect: ") 1159 } 1160 1161 invVect := &InvVect{ 1162 Type: InvType(typeUint), 1163 Hash: invHash, 1164 } 1165 1166 invList = append(invList, invVect) 1167 } 1168 1169 return invList, nil 1170 } 1171 1172 func (msg *MsgDeSoInv) ToBytes(preSignature bool) ([]byte, error) { 1173 data, err := _invListToBytes(msg.InvList) 1174 if err != nil { 1175 return nil, errors.Wrapf(err, "MsgDeSoGetInv: ") 1176 } 1177 data = append(data, BoolToByte(msg.IsSyncResponse)) 1178 1179 return data, nil 1180 } 1181 1182 func (msg *MsgDeSoInv) FromBytes(data []byte) error { 1183 rr := bytes.NewReader(data) 1184 invList, err := _readInvList(rr) 1185 if err != nil { 1186 return errors.Wrapf(err, "MsgDeSoInv: ") 1187 } 1188 isSyncResponse := ReadBoolByte(rr) 1189 1190 *msg = MsgDeSoInv{ 1191 InvList: invList, 1192 IsSyncResponse: isSyncResponse, 1193 } 1194 return nil 1195 } 1196 1197 func (msg *MsgDeSoInv) String() string { 1198 return fmt.Sprintf("Num invs: %v, SyncResponse: %v, InvList: %v", 1199 len(msg.InvList), msg.IsSyncResponse, msg.InvList) 1200 } 1201 1202 // ================================================================== 1203 // PING and PONG Messages 1204 // ================================================================== 1205 1206 type MsgDeSoPing struct { 1207 Nonce uint64 1208 } 1209 1210 func (msg *MsgDeSoPing) GetMsgType() MsgType { 1211 return MsgTypePing 1212 } 1213 1214 func (msg *MsgDeSoPing) ToBytes(preSignature bool) ([]byte, error) { 1215 return UintToBuf(msg.Nonce), nil 1216 } 1217 1218 func (msg *MsgDeSoPing) FromBytes(data []byte) error { 1219 nonce, err := ReadUvarint(bytes.NewReader(data)) 1220 if err != nil { 1221 return fmt.Errorf("MsgDeSoPing.FromBytes: %v", err) 1222 } 1223 *msg = MsgDeSoPing{Nonce: nonce} 1224 return nil 1225 } 1226 1227 type MsgDeSoPong struct { 1228 Nonce uint64 1229 } 1230 1231 func (msg *MsgDeSoPong) GetMsgType() MsgType { 1232 return MsgTypePong 1233 } 1234 1235 func (msg *MsgDeSoPong) ToBytes(preSignature bool) ([]byte, error) { 1236 return UintToBuf(msg.Nonce), nil 1237 } 1238 1239 func (msg *MsgDeSoPong) FromBytes(data []byte) error { 1240 nonce, err := ReadUvarint(bytes.NewReader(data)) 1241 if err != nil { 1242 return fmt.Errorf("MsgDeSoPong.FromBytes: %v", err) 1243 } 1244 *msg = MsgDeSoPong{Nonce: nonce} 1245 return nil 1246 } 1247 1248 // ================================================================== 1249 // VERSION Message 1250 // ================================================================== 1251 1252 type ServiceFlag uint64 1253 1254 const ( 1255 // SFFullNode is a flag used to indicate a peer is a full node. 1256 SFFullNode ServiceFlag = 1 << iota 1257 ) 1258 1259 type MsgDeSoVersion struct { 1260 // What is the current version we're on? 1261 Version uint64 1262 1263 // What are the services offered by this node? 1264 Services ServiceFlag 1265 1266 // The node's unix timestamp that we use to compute a 1267 // robust "network time" using NTP. 1268 TstampSecs int64 1269 1270 // Used to detect when a node connects to itself, which 1271 // we generally want to prevent. 1272 Nonce uint64 1273 1274 // Used as a "vanity plate" to identify different DeSo 1275 // clients. Mainly useful in analyzing the network at 1276 // a meta level, not in the protocol itself. 1277 UserAgent string 1278 1279 // The height of the last block on the main chain for 1280 // this node. 1281 // 1282 // TODO: We need to update this to uint64 1283 StartBlockHeight uint32 1284 1285 // MinFeeRateNanosPerKB is the minimum feerate that a peer will 1286 // accept from other peers when validating transactions. 1287 MinFeeRateNanosPerKB uint64 1288 } 1289 1290 func (msg *MsgDeSoVersion) ToBytes(preSignature bool) ([]byte, error) { 1291 retBytes := []byte{} 1292 1293 // Version 1294 // 1295 // We give each one of these its own scope to avoid issues where 1296 // nn accidentally gets recycled. 1297 retBytes = append(retBytes, UintToBuf(msg.Version)...) 1298 1299 // Services 1300 retBytes = append(retBytes, UintToBuf(uint64(msg.Services))...) 1301 1302 // TstampSecs 1303 retBytes = append(retBytes, IntToBuf(msg.TstampSecs)...) 1304 1305 // Nonce 1306 retBytes = append(retBytes, UintToBuf(msg.Nonce)...) 1307 1308 // UserAgent 1309 // 1310 // Strings are encoded by putting their length first as uvarints 1311 // then their values afterward as bytes. 1312 retBytes = append(retBytes, UintToBuf(uint64(len(msg.UserAgent)))...) 1313 retBytes = append(retBytes, msg.UserAgent...) 1314 1315 // StartBlockHeight 1316 retBytes = append(retBytes, UintToBuf(uint64(msg.StartBlockHeight))...) 1317 1318 // MinFeeRateNanosPerKB 1319 retBytes = append(retBytes, UintToBuf(uint64(msg.MinFeeRateNanosPerKB))...) 1320 1321 // JSONAPIPort - deprecated 1322 retBytes = append(retBytes, UintToBuf(uint64(0))...) 1323 1324 return retBytes, nil 1325 } 1326 1327 func (msg *MsgDeSoVersion) FromBytes(data []byte) error { 1328 rr := bytes.NewReader(data) 1329 retVer := MsgDeSoVersion{} 1330 1331 // Version 1332 // 1333 // We give each one of these its own scope to avoid issues where 1334 // a value accidentally gets recycled. 1335 { 1336 ver, err := ReadUvarint(rr) 1337 if err != nil { 1338 return errors.Wrapf(err, "MsgDeSoVersion.FromBytes: Problem converting msg.Version") 1339 } 1340 retVer.Version = ver 1341 } 1342 1343 // Services 1344 { 1345 services, err := ReadUvarint(rr) 1346 if err != nil { 1347 return errors.Wrapf(err, "MsgDeSoVersion.FromBytes: Problem converting msg.Services") 1348 } 1349 retVer.Services = ServiceFlag(services) 1350 } 1351 1352 // TstampSecs 1353 { 1354 tstampSecs, err := ReadVarint(rr) 1355 if err != nil { 1356 return errors.Wrapf(err, "MsgDeSoVersion.FromBytes: Problem converting msg.TstampSecs") 1357 } 1358 retVer.TstampSecs = tstampSecs 1359 } 1360 1361 // Nonce 1362 { 1363 nonce, err := ReadUvarint(rr) 1364 if err != nil { 1365 return errors.Wrapf(err, "MsgDeSoVersion.FromBytes: Problem converting msg.Nonce") 1366 } 1367 retVer.Nonce = nonce 1368 } 1369 1370 // UserAgent 1371 // 1372 // Strings are encoded by putting their length first as uvarints 1373 // then their values afterward as bytes. 1374 { 1375 strLen, err := ReadUvarint(rr) 1376 if err != nil { 1377 return errors.Wrapf(err, "MsgDeSoVersion.FromBytes: Problem reading length of msg.UserAgent") 1378 } 1379 if strLen > MaxMessagePayload { 1380 return fmt.Errorf("MsgDeSoVersion.FromBytes: Length msg.UserAgent %d larger than max allowed %d", strLen, MaxMessagePayload) 1381 } 1382 userAgent := make([]byte, strLen) 1383 _, err = io.ReadFull(rr, userAgent) 1384 if err != nil { 1385 return errors.Wrapf(err, "MsgDeSoVersion.FromBytes: Error reading msg.UserAgent") 1386 } 1387 retVer.UserAgent = string(userAgent) 1388 } 1389 1390 // StartBlockHeight 1391 { 1392 lastBlockHeight, err := ReadUvarint(rr) 1393 if err != nil || lastBlockHeight > math.MaxUint32 { 1394 return errors.Wrapf(err, "MsgDeSoVersion.FromBytes: Problem converting msg.LatestBlockHeight") 1395 } 1396 retVer.StartBlockHeight = uint32(lastBlockHeight) 1397 } 1398 1399 // MinFeeRateNanosPerKB 1400 { 1401 minFeeRateNanosPerKB, err := ReadUvarint(rr) 1402 if err != nil { 1403 return errors.Wrapf(err, "MsgDeSoVersion.FromBytes: Problem converting msg.MinFeeRateNanosPerKB") 1404 } 1405 retVer.MinFeeRateNanosPerKB = minFeeRateNanosPerKB 1406 } 1407 1408 // JSONAPIPort - deprecated 1409 { 1410 _, err := ReadUvarint(rr) 1411 if err != nil { 1412 return errors.Wrapf(err, "MsgDeSoVersion.FromBytes: Problem converting msg.JSONAPIPort") 1413 } 1414 } 1415 1416 *msg = retVer 1417 return nil 1418 } 1419 1420 func (msg *MsgDeSoVersion) GetMsgType() MsgType { 1421 return MsgTypeVersion 1422 } 1423 1424 // ================================================================== 1425 // ADDR Message 1426 // ================================================================== 1427 1428 const ( 1429 // MaxAddrsPerAddrMsg is the maximum number of addresses we allow in a single 1430 // addr message from a peer. 1431 MaxAddrsPerAddrMsg = 1000 1432 // AddrRelayIntervalSeconds is the amount of time we wait before relaying each 1433 // batch of addresses we've received recently. 1434 AddrRelayIntervalSeconds = 60 1435 1436 // RebroadcastNodeAddrIntervalMinutes is how often we broadcast our own address 1437 // to our peers. 1438 RebroadcastNodeAddrIntervalMinutes = 24 * 60 1439 ) 1440 1441 // SingleAddr is similar to the wire.NetAddress definition from the btcd guys. 1442 type SingleAddr struct { 1443 // Last time the address was seen. Encoded as number UNIX seconds on the wire. 1444 Timestamp time.Time 1445 1446 // Bitfield which identifies the services supported by the address. 1447 Services ServiceFlag 1448 1449 // IP address of the peer. Must be 4 or 16 bytes for IPV4 or IPV6 respectively. 1450 IP net.IP 1451 1452 // Port the peer is using. 1453 Port uint16 1454 } 1455 1456 func (addr *SingleAddr) StringWithPort(includePort bool) string { 1457 // Always include the port for localhost as it's useful for testing. 1458 if includePort || net.IP([]byte{127, 0, 0, 1}).Equal(addr.IP) { 1459 return fmt.Sprintf("%s:%d", addr.IP.String(), addr.Port) 1460 } 1461 1462 return addr.IP.String() 1463 } 1464 1465 func (addr *SingleAddr) String() string { 1466 return fmt.Sprintf("%s:%d", addr.IP.String(), addr.Port) 1467 } 1468 1469 type MsgDeSoAddr struct { 1470 // The definition of NetAddress as defined by the btcd guys works fine for 1471 // our purposes. The only difference is that for DeSo nodes, the Service 1472 // flag in the NetAddress is as we define it above in ServiceFlag. 1473 // Note that we also rewrite the serialization logic as well to avoid 1474 // relying on potentially crusty Bitcoin-related work-arounds going forward. 1475 AddrList []*SingleAddr 1476 } 1477 1478 func (msg *MsgDeSoAddr) ToBytes(preSignature bool) ([]byte, error) { 1479 retBytes := []byte{} 1480 1481 // Encode the number of addresses as a uvarint. 1482 retBytes = append(retBytes, UintToBuf(uint64(len(msg.AddrList)))...) 1483 1484 // Encode each address. 1485 for _, addr := range msg.AddrList { 1486 // Timestamp 1487 // Assume it's always positive. 1488 retBytes = append(retBytes, UintToBuf(uint64(addr.Timestamp.Unix()))...) 1489 1490 // Services 1491 retBytes = append(retBytes, UintToBuf(uint64(addr.Services))...) 1492 1493 // IP 1494 // Encode the length of the IP and then the actual bytes. 1495 retBytes = append(retBytes, UintToBuf(uint64(len(addr.IP[:])))...) 1496 retBytes = append(retBytes, addr.IP[:]...) 1497 1498 // Port 1499 retBytes = append(retBytes, UintToBuf(uint64(addr.Port))...) 1500 } 1501 1502 return retBytes, nil 1503 } 1504 1505 func (msg *MsgDeSoAddr) FromBytes(data []byte) error { 1506 rr := bytes.NewReader(data) 1507 retVer := MsgDeSoAddr{} 1508 1509 // Read the number of addresses encoded. 1510 numAddrs, err := ReadUvarint(rr) 1511 if err != nil { 1512 return errors.Wrapf(err, "MsgDeSoAddr.FromBytes: Problem reading numAddrs: ") 1513 } 1514 for ii := uint64(0); ii < numAddrs; ii++ { 1515 // Read each addr and add it to the AddrList. 1516 currentAddr := &SingleAddr{} 1517 1518 // Timestamp 1519 tstampSecs, err := ReadUvarint(rr) 1520 if err != nil { 1521 return errors.Wrapf(err, "MsgDeSoAddr.FromBytes: Problem reading tstamp: ") 1522 } 1523 currentAddr.Timestamp = time.Unix(int64(tstampSecs), 0) 1524 1525 // Services 1526 serviceUint, err := ReadUvarint(rr) 1527 if err != nil { 1528 return errors.Wrapf(err, "MsgDeSoAddr.FromBytes: Problem reading services: ") 1529 } 1530 currentAddr.Services = ServiceFlag(serviceUint) 1531 1532 // IP 1533 ipLen, err := ReadUvarint(rr) 1534 if err != nil { 1535 return errors.Wrapf(err, "MsgDeSoAddr.FromBytes: Problem reading IP: ") 1536 } 1537 if ipLen != 4 && ipLen != 16 { 1538 return fmt.Errorf("MsgDeSoAddr.FromBytes: IP length must be 4 or 16 bytes but was %d", ipLen) 1539 } 1540 currentAddr.IP = net.IP(make([]byte, ipLen)) 1541 _, err = io.ReadFull(rr, currentAddr.IP) 1542 if err != nil { 1543 return errors.Wrapf(err, "MsgDeSoAddr.FromBytes: Error reading IP") 1544 } 1545 1546 // Port 1547 port, err := ReadUvarint(rr) 1548 if err != nil { 1549 return errors.Wrapf(err, "MsgDeSoAddr.FromBytes: Problem reading port: ") 1550 } 1551 if port > math.MaxUint16 { 1552 return fmt.Errorf("MsgDeSoAddr.FromBytes: Port value %d exceeds max "+ 1553 "allowed %d", port, math.MaxUint16) 1554 } 1555 currentAddr.Port = uint16(port) 1556 1557 retVer.AddrList = append(retVer.AddrList, currentAddr) 1558 } 1559 1560 *msg = retVer 1561 return nil 1562 } 1563 1564 func (msg *MsgDeSoAddr) GetMsgType() MsgType { 1565 return MsgTypeAddr 1566 } 1567 1568 func (msg *MsgDeSoAddr) String() string { 1569 return fmt.Sprintf("Num addrs: %v, AddrList: %v", len(msg.AddrList), msg.AddrList) 1570 } 1571 1572 // ================================================================== 1573 // GET_ADDR Message 1574 // ================================================================== 1575 1576 type MsgDeSoGetAddr struct { 1577 } 1578 1579 func (msg *MsgDeSoGetAddr) ToBytes(preSignature bool) ([]byte, error) { 1580 return []byte{}, nil 1581 } 1582 1583 func (msg *MsgDeSoGetAddr) FromBytes(data []byte) error { 1584 return nil 1585 } 1586 1587 func (msg *MsgDeSoGetAddr) GetMsgType() MsgType { 1588 return MsgTypeGetAddr 1589 } 1590 1591 // ================================================================== 1592 // VERACK Message 1593 // ================================================================== 1594 1595 // VERACK messages have no payload. 1596 type MsgDeSoVerack struct { 1597 // A verack message must contain the nonce the peer received in the 1598 // initial version message. This ensures the peer that is communicating 1599 // with us actually controls the address she says she does similar to 1600 // "SYN Cookie" DDOS protection. 1601 Nonce uint64 1602 } 1603 1604 func (msg *MsgDeSoVerack) ToBytes(preSignature bool) ([]byte, error) { 1605 retBytes := []byte{} 1606 1607 // Nonce 1608 retBytes = append(retBytes, UintToBuf(msg.Nonce)...) 1609 return retBytes, nil 1610 } 1611 1612 func (msg *MsgDeSoVerack) FromBytes(data []byte) error { 1613 rr := bytes.NewReader(data) 1614 retMsg := NewMessage(MsgTypeVerack).(*MsgDeSoVerack) 1615 { 1616 nonce, err := ReadUvarint(rr) 1617 if err != nil { 1618 return errors.Wrapf(err, "MsgDeSoVerack.FromBytes: Problem reading Nonce") 1619 } 1620 retMsg.Nonce = nonce 1621 } 1622 *msg = *retMsg 1623 return nil 1624 } 1625 1626 func (msg *MsgDeSoVerack) GetMsgType() MsgType { 1627 return MsgTypeVerack 1628 } 1629 1630 // ================================================================== 1631 // HEADER Message 1632 // ================================================================== 1633 1634 // MsgDeSoHeader definition. 1635 // 1636 // Note that all of these fields must be encoded as *full* big-endian 1637 // ints/uints rather than varints. This is because these fields are hashed to 1638 // produce a block and allowing them to be varints will heavily 1639 // incentivize miners to keep them short, which corrupts their 1640 // actual utility. 1641 // 1642 // Additionally note that it's particularly important that headers be 1643 // space-efficient, since light clients will need to download an entire 1644 // history of them in order to be able to validate anything. 1645 type MsgDeSoHeader struct { 1646 // Note this is encoded as a fixed-width uint32 rather than a 1647 // uvarint or a uint64. 1648 Version uint32 1649 1650 // Hash of the previous block in the chain. 1651 PrevBlockHash *BlockHash 1652 1653 // The merkle root of all the transactions contained within the block. 1654 TransactionMerkleRoot *BlockHash 1655 1656 // The unix timestamp (in seconds) specifying when this block was 1657 // mined. 1658 TstampSecs uint64 1659 1660 // The height of the block this header corresponds to. 1661 Height uint64 1662 1663 // The nonce that is used by miners in order to produce valid blocks. 1664 // 1665 // Note: Before the upgrade from HeaderVersion0 to HeaderVersion1, miners would make 1666 // use of ExtraData in the BlockRewardMetadata to get extra nonces. However, this is 1667 // no longer needed since HeaderVersion1 upgraded the nonce to 64 bits from 32 bits. 1668 Nonce uint64 1669 1670 // An extra nonce that can be used to provice *even more* entropy for miners, in the 1671 // event that ASICs become powerful enough to have birthday problems in the future. 1672 ExtraNonce uint64 1673 } 1674 1675 func HeaderSizeBytes() int { 1676 header := NewMessage(MsgTypeHeader) 1677 headerBytes, _ := header.ToBytes(false) 1678 return len(headerBytes) 1679 } 1680 1681 func (msg *MsgDeSoHeader) EncodeHeaderVersion0(preSignature bool) ([]byte, error) { 1682 retBytes := []byte{} 1683 1684 // Version 1685 { 1686 scratchBytes := [4]byte{} 1687 binary.BigEndian.PutUint32(scratchBytes[:], msg.Version) 1688 retBytes = append(retBytes, scratchBytes[:]...) 1689 } 1690 1691 // PrevBlockHash 1692 prevBlockHash := msg.PrevBlockHash 1693 if prevBlockHash == nil { 1694 prevBlockHash = &BlockHash{} 1695 } 1696 retBytes = append(retBytes, prevBlockHash[:]...) 1697 1698 // TransactionMerkleRoot 1699 transactionMerkleRoot := msg.TransactionMerkleRoot 1700 if transactionMerkleRoot == nil { 1701 transactionMerkleRoot = &BlockHash{} 1702 } 1703 retBytes = append(retBytes, transactionMerkleRoot[:]...) 1704 1705 // TstampSecs 1706 { 1707 scratchBytes := [4]byte{} 1708 binary.LittleEndian.PutUint32(scratchBytes[:], uint32(msg.TstampSecs)) 1709 retBytes = append(retBytes, scratchBytes[:]...) 1710 } 1711 1712 // Height 1713 { 1714 scratchBytes := [4]byte{} 1715 // The height used to be a uint64 1716 binary.LittleEndian.PutUint32(scratchBytes[:], uint32(msg.Height)) 1717 retBytes = append(retBytes, scratchBytes[:]...) 1718 } 1719 1720 // Nonce 1721 { 1722 scratchBytes := [4]byte{} 1723 binary.LittleEndian.PutUint32(scratchBytes[:], uint32(msg.Nonce)) 1724 retBytes = append(retBytes, scratchBytes[:]...) 1725 } 1726 1727 return retBytes, nil 1728 } 1729 1730 func (msg *MsgDeSoHeader) EncodeHeaderVersion1(preSignature bool) ([]byte, error) { 1731 retBytes := []byte{} 1732 1733 // Version 1734 { 1735 scratchBytes := [4]byte{} 1736 binary.BigEndian.PutUint32(scratchBytes[:], msg.Version) 1737 retBytes = append(retBytes, scratchBytes[:]...) 1738 } 1739 1740 // PrevBlockHash 1741 prevBlockHash := msg.PrevBlockHash 1742 if prevBlockHash == nil { 1743 prevBlockHash = &BlockHash{} 1744 } 1745 retBytes = append(retBytes, prevBlockHash[:]...) 1746 1747 // TransactionMerkleRoot 1748 transactionMerkleRoot := msg.TransactionMerkleRoot 1749 if transactionMerkleRoot == nil { 1750 transactionMerkleRoot = &BlockHash{} 1751 } 1752 retBytes = append(retBytes, transactionMerkleRoot[:]...) 1753 1754 // TstampSecs 1755 { 1756 scratchBytes := [8]byte{} 1757 binary.BigEndian.PutUint64(scratchBytes[:], msg.TstampSecs) 1758 retBytes = append(retBytes, scratchBytes[:]...) 1759 1760 // TODO: Don't allow this field to exceed 32-bits for now. This will 1761 // adjust once other parts of the code are fixed to handle the wider 1762 // type. 1763 if msg.TstampSecs > math.MaxUint32 { 1764 return nil, fmt.Errorf("EncodeHeaderVersion1: TstampSecs not yet allowed " + 1765 "to exceed max uint32. This will be fixed in the future") 1766 } 1767 } 1768 1769 // Height 1770 { 1771 scratchBytes := [8]byte{} 1772 binary.BigEndian.PutUint64(scratchBytes[:], msg.Height) 1773 retBytes = append(retBytes, scratchBytes[:]...) 1774 1775 // TODO: Don't allow this field to exceed 32-bits for now. This will 1776 // adjust once other parts of the code are fixed to handle the wider 1777 // type. 1778 if msg.Height > math.MaxUint32 { 1779 return nil, fmt.Errorf("EncodeHeaderVersion1: Height not yet allowed " + 1780 "to exceed max uint32. This will be fixed in the future") 1781 } 1782 } 1783 1784 // Nonce 1785 { 1786 scratchBytes := [8]byte{} 1787 binary.BigEndian.PutUint64(scratchBytes[:], msg.Nonce) 1788 retBytes = append(retBytes, scratchBytes[:]...) 1789 } 1790 1791 // ExtraNonce 1792 { 1793 scratchBytes := [8]byte{} 1794 binary.BigEndian.PutUint64(scratchBytes[:], msg.ExtraNonce) 1795 retBytes = append(retBytes, scratchBytes[:]...) 1796 } 1797 1798 return retBytes, nil 1799 } 1800 1801 func (msg *MsgDeSoHeader) ToBytes(preSignature bool) ([]byte, error) { 1802 1803 // Depending on the version, we decode the header differently. 1804 if msg.Version == HeaderVersion0 { 1805 return msg.EncodeHeaderVersion0(preSignature) 1806 } else if msg.Version == HeaderVersion1 { 1807 return msg.EncodeHeaderVersion1(preSignature) 1808 } else { 1809 // If we have an unrecognized version then we default to serializing with 1810 // version 0. This is necessary because there are places where we use a 1811 // MsgDeSoHeader struct to store Bitcoin headers. 1812 return msg.EncodeHeaderVersion0(preSignature) 1813 } 1814 } 1815 1816 func DecodeHeaderVersion0(rr io.Reader) (*MsgDeSoHeader, error) { 1817 retHeader := NewMessage(MsgTypeHeader).(*MsgDeSoHeader) 1818 1819 // PrevBlockHash 1820 _, err := io.ReadFull(rr, retHeader.PrevBlockHash[:]) 1821 if err != nil { 1822 return nil, errors.Wrapf(err, "MsgDeSoHeader.FromBytes: Problem decoding PrevBlockHash") 1823 } 1824 1825 // TransactionMerkleRoot 1826 _, err = io.ReadFull(rr, retHeader.TransactionMerkleRoot[:]) 1827 if err != nil { 1828 return nil, errors.Wrapf(err, "MsgDeSoHeader.FromBytes: Problem decoding TransactionMerkleRoot") 1829 } 1830 1831 // TstampSecs 1832 { 1833 scratchBytes := [4]byte{} 1834 _, err := io.ReadFull(rr, scratchBytes[:]) 1835 if err != nil { 1836 return nil, errors.Wrapf(err, "MsgDeSoHeader.FromBytes: Problem decoding TstampSecs") 1837 } 1838 retHeader.TstampSecs = uint64(binary.LittleEndian.Uint32(scratchBytes[:])) 1839 } 1840 1841 // Height 1842 { 1843 scratchBytes := [4]byte{} 1844 _, err := io.ReadFull(rr, scratchBytes[:]) 1845 if err != nil { 1846 return nil, errors.Wrapf(err, "MsgDeSoHeader.FromBytes: Problem decoding Height") 1847 } 1848 retHeader.Height = uint64(binary.LittleEndian.Uint32(scratchBytes[:])) 1849 } 1850 1851 // Nonce 1852 { 1853 scratchBytes := [4]byte{} 1854 _, err := io.ReadFull(rr, scratchBytes[:]) 1855 if err != nil { 1856 return nil, errors.Wrapf(err, "MsgDeSoHeader.FromBytes: Problem decoding Nonce") 1857 } 1858 retHeader.Nonce = uint64(binary.LittleEndian.Uint32(scratchBytes[:])) 1859 } 1860 1861 return retHeader, nil 1862 } 1863 1864 func DecodeHeaderVersion1(rr io.Reader) (*MsgDeSoHeader, error) { 1865 retHeader := NewMessage(MsgTypeHeader).(*MsgDeSoHeader) 1866 1867 // PrevBlockHash 1868 _, err := io.ReadFull(rr, retHeader.PrevBlockHash[:]) 1869 if err != nil { 1870 return nil, errors.Wrapf(err, "MsgDeSoHeader.FromBytes: Problem decoding PrevBlockHash") 1871 } 1872 1873 // TransactionMerkleRoot 1874 _, err = io.ReadFull(rr, retHeader.TransactionMerkleRoot[:]) 1875 if err != nil { 1876 return nil, errors.Wrapf(err, "MsgDeSoHeader.FromBytes: Problem decoding TransactionMerkleRoot") 1877 } 1878 1879 // TstampSecs 1880 { 1881 scratchBytes := [8]byte{} 1882 _, err := io.ReadFull(rr, scratchBytes[:]) 1883 if err != nil { 1884 return nil, errors.Wrapf(err, "MsgDeSoHeader.FromBytes: Problem decoding TstampSecs") 1885 } 1886 retHeader.TstampSecs = binary.BigEndian.Uint64(scratchBytes[:]) 1887 } 1888 1889 // Height 1890 { 1891 scratchBytes := [8]byte{} 1892 _, err := io.ReadFull(rr, scratchBytes[:]) 1893 if err != nil { 1894 return nil, errors.Wrapf(err, "MsgDeSoHeader.FromBytes: Problem decoding Height") 1895 } 1896 retHeader.Height = binary.BigEndian.Uint64(scratchBytes[:]) 1897 } 1898 1899 // Nonce 1900 { 1901 scratchBytes := [8]byte{} 1902 _, err := io.ReadFull(rr, scratchBytes[:]) 1903 if err != nil { 1904 return nil, errors.Wrapf(err, "MsgDeSoHeader.FromBytes: Problem decoding Nonce") 1905 } 1906 retHeader.Nonce = binary.BigEndian.Uint64(scratchBytes[:]) 1907 } 1908 1909 // ExtraNonce 1910 { 1911 scratchBytes := [8]byte{} 1912 _, err := io.ReadFull(rr, scratchBytes[:]) 1913 if err != nil { 1914 return nil, errors.Wrapf(err, "MsgDeSoHeader.FromBytes: Problem decoding ExtraNonce") 1915 } 1916 retHeader.ExtraNonce = binary.BigEndian.Uint64(scratchBytes[:]) 1917 } 1918 1919 return retHeader, nil 1920 } 1921 1922 func DecodeHeader(rr io.Reader) (*MsgDeSoHeader, error) { 1923 // Read the version to determine 1924 scratchBytes := [4]byte{} 1925 _, err := io.ReadFull(rr, scratchBytes[:]) 1926 if err != nil { 1927 return nil, errors.Wrapf(err, "MsgDeSoHeader.FromBytes: Problem decoding Version") 1928 } 1929 headerVersion := binary.BigEndian.Uint32(scratchBytes[:]) 1930 1931 var ret *MsgDeSoHeader 1932 if headerVersion == HeaderVersion0 { 1933 ret, err = DecodeHeaderVersion0(rr) 1934 } else if headerVersion == HeaderVersion1 { 1935 ret, err = DecodeHeaderVersion1(rr) 1936 } else { 1937 // If we have an unrecognized version then we default to de-serializing with 1938 // version 0. This is necessary because there are places where we use a 1939 // MsgDeSoHeader struct to store Bitcoin headers. 1940 ret, err = DecodeHeaderVersion0(rr) 1941 } 1942 if err != nil { 1943 return nil, fmt.Errorf( 1944 "DecodeHeader: Unrecognized header version: %v", headerVersion) 1945 } 1946 // Set the version since it's not decoded in the version-specific handlers. 1947 ret.Version = headerVersion 1948 1949 return ret, nil 1950 } 1951 1952 func (msg *MsgDeSoHeader) FromBytes(data []byte) error { 1953 rr := bytes.NewReader(data) 1954 retHeader, err := DecodeHeader(rr) 1955 if err != nil { 1956 return fmt.Errorf("MsgDeSoHeader.FromBytes: %v", err) 1957 } 1958 1959 *msg = *retHeader 1960 return nil 1961 } 1962 1963 func (msg *MsgDeSoHeader) GetMsgType() MsgType { 1964 return MsgTypeHeader 1965 } 1966 1967 // Hash is a helper function to compute a hash of the header. Note that the header 1968 // hash is special in that we always hash it using the ProofOfWorkHash rather than 1969 // Sha256DoubleHash. 1970 func (msg *MsgDeSoHeader) Hash() (*BlockHash, error) { 1971 preSignature := false 1972 headerBytes, err := msg.ToBytes(preSignature) 1973 if err != nil { 1974 return nil, errors.Wrap(err, "MsgDeSoHeader.Hash: ") 1975 } 1976 1977 return ProofOfWorkHash(headerBytes, msg.Version), nil 1978 } 1979 1980 func (msg *MsgDeSoHeader) String() string { 1981 hash, _ := msg.Hash() 1982 return fmt.Sprintf("< %d, %s, %v >", msg.Height, hash, msg.Version) 1983 } 1984 1985 // ================================================================== 1986 // BLOCK Message 1987 // ================================================================== 1988 1989 type BlockProducerInfo struct { 1990 PublicKey []byte 1991 Signature *btcec.Signature 1992 } 1993 1994 func (bpi *BlockProducerInfo) Serialize() []byte { 1995 data := []byte{} 1996 data = append(data, UintToBuf(uint64(len(bpi.PublicKey)))...) 1997 data = append(data, bpi.PublicKey...) 1998 1999 sigBytes := []byte{} 2000 if bpi.Signature != nil { 2001 sigBytes = bpi.Signature.Serialize() 2002 } 2003 data = append(data, UintToBuf(uint64(len(sigBytes)))...) 2004 data = append(data, sigBytes...) 2005 2006 return data 2007 } 2008 2009 func (bpi *BlockProducerInfo) Deserialize(data []byte) error { 2010 ret := &BlockProducerInfo{} 2011 rr := bytes.NewReader(data) 2012 2013 // De-serialize the public key. 2014 { 2015 pkLen, err := ReadUvarint(rr) 2016 if err != nil { 2017 return errors.Wrapf(err, "BlockProducerInfo.Deserialize: Error reading public key len") 2018 } 2019 if pkLen > MaxMessagePayload { 2020 return errors.Wrapf(err, "BlockProducerInfo.Deserialize: pkLen too long: %v", pkLen) 2021 } 2022 pkBytes := make([]byte, pkLen) 2023 _, err = io.ReadFull(rr, pkBytes) 2024 if err != nil { 2025 return errors.Wrapf(err, "BlockProducerInfo.Deserialize: Error reading public key: ") 2026 } 2027 ret.PublicKey = pkBytes 2028 } 2029 2030 // De-serialize the signature. 2031 { 2032 sigLen, err := ReadUvarint(rr) 2033 if err != nil { 2034 return errors.Wrapf(err, "BlockProducerInfo.Deserialize: Error reading signature len") 2035 } 2036 if sigLen > MaxMessagePayload { 2037 return errors.Wrapf(err, "BlockProducerInfo.Deserialize: signature len too long: %v", sigLen) 2038 } 2039 sigBytes := make([]byte, sigLen) 2040 _, err = io.ReadFull(rr, sigBytes) 2041 if err != nil { 2042 return errors.Wrapf(err, "BlockProducerInfo.Deserialize: Error reading signature: ") 2043 } 2044 ret.Signature = nil 2045 if sigLen > 0 { 2046 sig, err := btcec.ParseDERSignature(sigBytes, btcec.S256()) 2047 if err != nil { 2048 return errors.Wrapf(err, "BlockProducerInfo.Deserialize: Error parsing signature bytes: ") 2049 } 2050 ret.Signature = sig 2051 } 2052 } 2053 2054 *bpi = *ret 2055 return nil 2056 } 2057 2058 func (bpi *BlockProducerInfo) String() string { 2059 if bpi == nil || len(bpi.PublicKey) == 0 { 2060 return "Signer Key: NONE" 2061 } 2062 return fmt.Sprintf("Signer Key: %v", PkToStringMainnet(bpi.PublicKey)) 2063 } 2064 2065 type MsgDeSoBlock struct { 2066 Header *MsgDeSoHeader 2067 Txns []*MsgDeSoTxn 2068 2069 // This field is optional and provides the producer of the block the ability to sign it 2070 // with their private key. Doing this proves that this block was produced by a particular 2071 // entity, which can be useful for nodes that want to restrict who they accept blocks 2072 // from. 2073 BlockProducerInfo *BlockProducerInfo 2074 } 2075 2076 func (msg *MsgDeSoBlock) EncodeBlockCommmon(preSignature bool) ([]byte, error) { 2077 data := []byte{} 2078 2079 // Serialize the header. 2080 if msg.Header == nil { 2081 return nil, fmt.Errorf("MsgDeSoBlock.ToBytes: Header should not be nil") 2082 } 2083 hdrBytes, err := msg.Header.ToBytes(preSignature) 2084 if err != nil { 2085 return nil, errors.Wrapf(err, "MsgDeSoBlock.ToBytes: Problem encoding header") 2086 } 2087 data = append(data, UintToBuf(uint64(len(hdrBytes)))...) 2088 data = append(data, hdrBytes...) 2089 2090 // Serialize all the transactions. 2091 numTxns := uint64(len(msg.Txns)) 2092 data = append(data, UintToBuf(numTxns)...) 2093 for ii := uint64(0); ii < numTxns; ii++ { 2094 currentTxnBytes, err := msg.Txns[ii].ToBytes(preSignature) 2095 if err != nil { 2096 return nil, errors.Wrapf(err, "MsgDeSoBlock.ToBytes: Problem encoding txn") 2097 } 2098 data = append(data, UintToBuf(uint64(len(currentTxnBytes)))...) 2099 data = append(data, currentTxnBytes...) 2100 } 2101 2102 return data, nil 2103 } 2104 2105 func (msg *MsgDeSoBlock) EncodeBlockVersion0(preSignature bool) ([]byte, error) { 2106 return msg.EncodeBlockCommmon(preSignature) 2107 } 2108 2109 func (msg *MsgDeSoBlock) EncodeBlockVersion1(preSignature bool) ([]byte, error) { 2110 data, err := msg.EncodeBlockCommmon(preSignature) 2111 if err != nil { 2112 return nil, err 2113 } 2114 2115 // BlockProducerInfo 2116 blockProducerInfoBytes := []byte{} 2117 if msg.BlockProducerInfo != nil { 2118 blockProducerInfoBytes = msg.BlockProducerInfo.Serialize() 2119 } 2120 data = append(data, UintToBuf(uint64(len(blockProducerInfoBytes)))...) 2121 data = append(data, blockProducerInfoBytes...) 2122 2123 return data, nil 2124 } 2125 2126 func (msg *MsgDeSoBlock) ToBytes(preSignature bool) ([]byte, error) { 2127 if msg.Header.Version == HeaderVersion0 { 2128 return msg.EncodeBlockVersion0(preSignature) 2129 } else if msg.Header.Version == HeaderVersion1 { 2130 return msg.EncodeBlockVersion1(preSignature) 2131 } else { 2132 return nil, fmt.Errorf("MsgDeSoBlock.ToBytes: Error encoding version: %v", msg.Header.Version) 2133 } 2134 } 2135 2136 func (msg *MsgDeSoBlock) FromBytes(data []byte) error { 2137 ret := NewMessage(MsgTypeBlock).(*MsgDeSoBlock) 2138 rr := bytes.NewReader(data) 2139 2140 // De-serialize the header. 2141 hdrLen, err := ReadUvarint(rr) 2142 if err != nil { 2143 return errors.Wrapf(err, "MsgDeSoBlock.FromBytes: Problem decoding header length") 2144 } 2145 if hdrLen > MaxMessagePayload { 2146 return fmt.Errorf("MsgDeSoBlock.FromBytes: Header length %d longer than max %d", hdrLen, MaxMessagePayload) 2147 } 2148 hdrBytes := make([]byte, hdrLen) 2149 _, err = io.ReadFull(rr, hdrBytes) 2150 if err != nil { 2151 return errors.Wrapf(err, "MsgDeSoBlock.FromBytes: Problem reading header") 2152 } 2153 2154 err = ret.Header.FromBytes(hdrBytes) 2155 if err != nil { 2156 return errors.Wrapf(err, "MsgDeSoBlock.FromBytes: Problem converting header") 2157 } 2158 2159 // De-serialize the transactions. 2160 numTxns, err := ReadUvarint(rr) 2161 if err != nil { 2162 return errors.Wrapf(err, "MsgDeSoBlock.FromBytes: Problem decoding num txns") 2163 } 2164 ret.Txns = make([]*MsgDeSoTxn, 0) 2165 for ii := uint64(0); ii < numTxns; ii++ { 2166 txBytesLen, err := ReadUvarint(rr) 2167 if err != nil { 2168 return errors.Wrapf(err, "MsgDeSoBlock.FromBytes: Problem decoding txn length") 2169 } 2170 if txBytesLen > MaxMessagePayload { 2171 return fmt.Errorf("MsgDeSoBlock.FromBytes: Txn %d length %d longer than max %d", ii, hdrLen, MaxMessagePayload) 2172 } 2173 txBytes := make([]byte, txBytesLen) 2174 _, err = io.ReadFull(rr, txBytes) 2175 if err != nil { 2176 return errors.Wrapf(err, "MsgDeSoBlock.FromBytes: Problem reading tx bytes") 2177 } 2178 currentTxn := NewMessage(MsgTypeTxn).(*MsgDeSoTxn) 2179 err = currentTxn.FromBytes(txBytes) 2180 if err != nil { 2181 return errors.Wrapf(err, "MsgDeSoBlock.FromBytes: Problem decoding txn") 2182 } 2183 ret.Txns = append(ret.Txns, currentTxn) 2184 } 2185 2186 // Version 1 blocks have a BlockProducerInfo attached to them that 2187 // must be read. If this is not a Version 1 block, then the BlockProducerInfo 2188 // remains nil. 2189 if ret.Header.Version == HeaderVersion1 { 2190 blockProducerInfoLen, err := ReadUvarint(rr) 2191 if err != nil { 2192 return errors.Wrapf(err, "MsgDeSoBlock.FromBytes: Error decoding header length") 2193 } 2194 var blockProducerInfo *BlockProducerInfo 2195 if blockProducerInfoLen > 0 { 2196 if blockProducerInfoLen > MaxMessagePayload { 2197 return fmt.Errorf("MsgDeSoBlock.FromBytes: Header length %d longer "+ 2198 "than max %d", blockProducerInfoLen, MaxMessagePayload) 2199 } 2200 blockProducerInfoBytes := make([]byte, blockProducerInfoLen) 2201 _, err = io.ReadFull(rr, blockProducerInfoBytes) 2202 if err != nil { 2203 return errors.Wrapf(err, "MsgDeSoBlock.FromBytes: Problem reading header") 2204 } 2205 blockProducerInfo = &BlockProducerInfo{} 2206 blockProducerInfo.Deserialize(blockProducerInfoBytes) 2207 ret.BlockProducerInfo = blockProducerInfo 2208 } 2209 } 2210 2211 *msg = *ret 2212 return nil 2213 } 2214 2215 func (msg *MsgDeSoBlock) GetMsgType() MsgType { 2216 return MsgTypeBlock 2217 } 2218 2219 func (msg *MsgDeSoBlock) Hash() (*BlockHash, error) { 2220 if msg == nil || msg.Header == nil { 2221 return nil, fmt.Errorf("MsgDeSoBLock.Hash: nil block or nil header") 2222 } 2223 return msg.Header.Hash() 2224 } 2225 2226 func (msg *MsgDeSoBlock) String() string { 2227 if msg == nil || msg.Header == nil { 2228 return "<nil block or header>" 2229 } 2230 return fmt.Sprintf("<Header: %v, %v>", msg.Header.String(), msg.BlockProducerInfo) 2231 } 2232 2233 // ================================================================== 2234 // TXN Message 2235 // ================================================================== 2236 2237 // UtxoKey is a 32-byte txid with a 4-byte uint32 index 2238 // identifying the particular output in the transaction where 2239 // this utxo occurs. 2240 // When fetching from the db the txid and index are concatenated to 2241 // form the key, with the index serialized as big-endian. 2242 type UtxoKey struct { 2243 // The 32-byte transaction id where the unspent output occurs. 2244 TxID BlockHash 2245 // The index within the txn where the unspent output occurs. 2246 Index uint32 2247 } 2248 2249 func (utxoKey *UtxoKey) String() string { 2250 return fmt.Sprintf("< TxID: %v, Index: %d >", &utxoKey.TxID, utxoKey.Index) 2251 } 2252 2253 const ( 2254 // MaxDeSoInputSizeBytes is the size required to encode an DeSoInput. 2255 // 32 bytes for the TxID and 4 bytes for the Index = 36 bytes. Note 2256 // that because the index is encoded as a uvarint, this size represents 2257 // a maximum. 2258 MaxDeSoInputSizeBytes = 32 + 4 2259 // MaxDeSoOutputSizeBytes is the size required to encode an DeSoOutput. 2260 // It is 33 bytes for the public key and 8 bytes for the amount 2261 // = 41 bytes. Note that because the amount is encoded as a uvarint, 2262 // this size represents a maximum. 2263 MaxDeSoOutputSizeBytes = btcec.PubKeyBytesLenCompressed + 8 2264 ) 2265 2266 // DeSoInput represents a single unspent output from a previous txn. 2267 // For that reason it specifies the previous txn and the index in that txn where 2268 // the output appears by simply aliasing UtxoKey. 2269 type DeSoInput UtxoKey 2270 2271 func (desoInput *DeSoInput) String() string { 2272 return (*UtxoKey)(desoInput).String() 2273 } 2274 2275 func NewDeSoInput() *DeSoInput { 2276 return &DeSoInput{ 2277 TxID: BlockHash{}, 2278 } 2279 } 2280 2281 type DeSoOutput struct { 2282 // Outputs always compensate a specific public key. 2283 PublicKey []byte 2284 // The amount of DeSo to send to this public key. 2285 AmountNanos uint64 2286 } 2287 2288 func (desoOutput *DeSoOutput) String() string { 2289 return fmt.Sprintf("< PublicKey: %#v, AmountNanos: %d >", 2290 PkToStringMainnet(desoOutput.PublicKey), desoOutput.AmountNanos) 2291 } 2292 2293 type MsgDeSoTxn struct { 2294 TxInputs []*DeSoInput 2295 TxOutputs []*DeSoOutput 2296 2297 // DeSoTxnMetadata is an interface type that will give us information on how 2298 // we should handle the transaction, including what type of transaction this 2299 // is. 2300 TxnMeta DeSoTxnMetadata 2301 2302 // Transactions must generally explicitly include the key that is 2303 // spending the inputs to the transaction. The exception to this rule is that 2304 // BlockReward and BitcoinExchange transactions do not require the inclusion 2305 // of a public key since they have no inputs to spend. 2306 // 2307 // The public key should be a serialized compressed ECDSA public key on the 2308 // secp256k1 curve. 2309 PublicKey []byte 2310 2311 // This is typically a JSON field that can be used to add extra information to 2312 // a transaction without causing a hard fork. It is useful in rare cases where we 2313 // realize that something needs to be added to a transaction but where we can't 2314 // afford a hard fork. 2315 ExtraData map[string][]byte 2316 2317 // Transactions must generally be signed by the key that is spending the 2318 // inputs to the transaction. The exception to this rule is that 2319 // BLOCK_REWARD and CREATE_deso transactions do not require a signature 2320 // since they have no inputs. 2321 Signature *btcec.Signature 2322 2323 // (!!) **DO_NOT_USE** (!!) 2324 // 2325 // Use txn.TxnMeta.GetTxnType() instead. 2326 // 2327 // We need this for JSON encoding/decoding. It isn't used for anything 2328 // else and it isn't actually serialized or de-serialized when sent 2329 // across the network using ToBytes/FromBytes because we prefer that 2330 // any use of the MsgDeSoTxn in Go code rely on TxnMeta.GetTxnType() rather 2331 // than checking this value, which, in Go context, is redundant and 2332 // therefore error-prone (e.g. someone might change TxnMeta while 2333 // forgetting to set it). We make it a uint64 explicitly to prevent 2334 // people from using it in Go code. 2335 TxnTypeJSON uint64 2336 } 2337 2338 func (msg *MsgDeSoTxn) String() string { 2339 pubKey := msg.PublicKey 2340 if msg.TxnMeta.GetTxnType() == TxnTypeBitcoinExchange { 2341 pubKeyObj, err := ExtractBitcoinPublicKeyFromBitcoinTransactionInputs( 2342 msg.TxnMeta.(*BitcoinExchangeMetadata).BitcoinTransaction, DeSoMainnetParams.BitcoinBtcdParams) 2343 if err != nil { 2344 pubKey = msg.PublicKey 2345 } else { 2346 pubKey = pubKeyObj.SerializeCompressed() 2347 } 2348 } 2349 return fmt.Sprintf("< TxHash: %v, TxnType: %v, PubKey: %v >", 2350 msg.Hash(), msg.TxnMeta.GetTxnType(), PkToStringMainnet(pubKey)) 2351 } 2352 2353 func (msg *MsgDeSoTxn) ToBytes(preSignature bool) ([]byte, error) { 2354 data := []byte{} 2355 2356 // Serialize the inputs 2357 data = append(data, UintToBuf(uint64(len(msg.TxInputs)))...) 2358 for _, desoInput := range msg.TxInputs { 2359 data = append(data, desoInput.TxID[:]...) 2360 data = append(data, UintToBuf(uint64(desoInput.Index))...) 2361 } 2362 2363 // Serialize the outputs 2364 data = append(data, UintToBuf(uint64(len(msg.TxOutputs)))...) 2365 for _, desoOutput := range msg.TxOutputs { 2366 // The public key is always 33 bytes. 2367 data = append(data, desoOutput.PublicKey[:]...) 2368 data = append(data, UintToBuf(desoOutput.AmountNanos)...) 2369 } 2370 2371 // Serialize the metadata 2372 // 2373 // Encode the type as a uvarint. 2374 data = append(data, UintToBuf(uint64(msg.TxnMeta.GetTxnType()))...) 2375 // Encode the length and payload for the metadata. 2376 // 2377 // Note that we do *NOT* serialize the metadata using the preSignature 2378 // flag. This is the correct thing to do since by the time we're ready 2379 // to serialize the full transaction, all of the metadata should have 2380 // its signatures fully computed. As a result, the proper way to use 2381 // the preSignature flag when metadata is involved is as follows: 2382 // - Compute the bytes for the meta using preSignature=true 2383 // - Sign the bytes for the meta however that particular metadata 2384 // requires. 2385 // - Compute the bytes for the full transaction using preSignature=true. 2386 // This will fully-serialize the meta with its computed signature, 2387 // which is correct. 2388 // - Sign the bytes for the full transaction from above. 2389 preSignatureForMeta := false 2390 metadataBuf, err := msg.TxnMeta.ToBytes(preSignatureForMeta) 2391 if err != nil { 2392 return nil, errors.Wrapf(err, "MsgDeSoTxn.ToBytes: Problem encoding meta of type %v: ", 2393 msg.TxnMeta.GetTxnType()) 2394 } 2395 data = append(data, UintToBuf(uint64(len(metadataBuf)))...) 2396 data = append(data, metadataBuf...) 2397 2398 // Serialize the public key if there is one. Encode the length in 2399 // case this field was left empty. 2400 data = append(data, UintToBuf(uint64(len(msg.PublicKey)))...) 2401 data = append(data, msg.PublicKey...) 2402 2403 // ExtraData 2404 extraDataLength := uint64(len(msg.ExtraData)) 2405 data = append(data, UintToBuf(extraDataLength)...) 2406 if extraDataLength > 0 { 2407 // Sort the keys of the map 2408 keys := make([]string, 0, len(msg.ExtraData)) 2409 for key := range msg.ExtraData { 2410 keys = append(keys, key) 2411 } 2412 sort.Strings(keys) 2413 // Encode the length of the key, the key itself 2414 // then the length of the value, then the value itself. 2415 for _, key := range keys { 2416 data = append(data, UintToBuf(uint64(len(key)))...) 2417 data = append(data, []byte(key)...) 2418 value := msg.ExtraData[key] 2419 data = append(data, UintToBuf(uint64(len(value)))...) 2420 data = append(data, value...) 2421 } 2422 } 2423 2424 // Serialize the signature. Since this can be variable length, encode 2425 // the length first and then the signature. If there is no signature, then 2426 // a zero will be encoded for the length and no signature bytes will be added 2427 // beyond it. 2428 sigBytes := []byte{} 2429 if !preSignature && msg.Signature != nil { 2430 sigBytes = msg.Signature.Serialize() 2431 } 2432 // Note that even though we encode the length as a varint as opposed to a 2433 // fixed-width int, it should always take up just one byte since the length 2434 // of the signature will never exceed 127 bytes in length. This is important 2435 // to note for e.g. operations that try to compute a transaction's size 2436 // before a signature is present such as during transaction fee computations. 2437 data = append(data, UintToBuf(uint64(len(sigBytes)))...) 2438 data = append(data, sigBytes...) 2439 2440 return data, nil 2441 } 2442 2443 func _readTransaction(rr io.Reader) (*MsgDeSoTxn, error) { 2444 ret := NewMessage(MsgTypeTxn).(*MsgDeSoTxn) 2445 2446 // De-serialize the inputs 2447 numInputs, err := ReadUvarint(rr) 2448 if err != nil { 2449 return nil, errors.Wrapf(err, "_readTransaction: Problem converting len(msg.TxInputs)") 2450 } 2451 for ii := uint64(0); ii < numInputs; ii++ { 2452 currentInput := NewDeSoInput() 2453 _, err = io.ReadFull(rr, currentInput.TxID[:]) 2454 if err != nil { 2455 return nil, errors.Wrapf(err, "_readTransaction: Problem converting input txid") 2456 } 2457 inputIndex, err := ReadUvarint(rr) 2458 if err != nil { 2459 return nil, errors.Wrapf(err, "_readTransaction: Problem converting input index") 2460 } 2461 if inputIndex > uint64(^uint32(0)) { 2462 return nil, fmt.Errorf("_readTransaction: Input index (%d) must not exceed (%d)", inputIndex, ^uint32(0)) 2463 } 2464 currentInput.Index = uint32(inputIndex) 2465 2466 ret.TxInputs = append(ret.TxInputs, currentInput) 2467 } 2468 2469 // De-serialize the outputs 2470 numOutputs, err := ReadUvarint(rr) 2471 if err != nil { 2472 return nil, errors.Wrapf(err, "_readTransaction: Problem converting len(msg.TxOutputs)") 2473 } 2474 for ii := uint64(0); ii < numOutputs; ii++ { 2475 currentOutput := &DeSoOutput{} 2476 currentOutput.PublicKey = make([]byte, btcec.PubKeyBytesLenCompressed) 2477 _, err = io.ReadFull(rr, currentOutput.PublicKey) 2478 if err != nil { 2479 return nil, errors.Wrapf(err, "_readTransaction: Problem reading DeSoOutput.PublicKey") 2480 } 2481 2482 amountNanos, err := ReadUvarint(rr) 2483 if err != nil { 2484 return nil, errors.Wrapf(err, "_readTransaction: Problem reading DeSoOutput.AmountNanos") 2485 } 2486 currentOutput.AmountNanos = amountNanos 2487 2488 ret.TxOutputs = append(ret.TxOutputs, currentOutput) 2489 } 2490 2491 // De-serialize the metadata 2492 // 2493 // Encode the type as a uvarint. 2494 txnMetaType, err := ReadUvarint(rr) 2495 if err != nil { 2496 return nil, errors.Wrapf(err, "_readTransaction: Problem reading MsgDeSoTxn.TxnType") 2497 } 2498 ret.TxnMeta, err = NewTxnMetadata(TxnType(txnMetaType)) 2499 if err != nil { 2500 return nil, fmt.Errorf("_readTransaction: Problem initializing metadata: %v", err) 2501 } 2502 if ret.TxnMeta == nil { 2503 return nil, fmt.Errorf("_readTransaction: Metadata was nil: %v", ret.TxnMeta) 2504 } 2505 metaLen, err := ReadUvarint(rr) 2506 if err != nil { 2507 return nil, errors.Wrapf(err, "_readTransaction: Problem reading len(TxnMeta)") 2508 } 2509 if metaLen > MaxMessagePayload { 2510 return nil, fmt.Errorf("_readTransaction.FromBytes: metaLen length %d longer than max %d", metaLen, MaxMessagePayload) 2511 } 2512 metaBuf := make([]byte, metaLen) 2513 _, err = io.ReadFull(rr, metaBuf) 2514 if err != nil { 2515 return nil, errors.Wrapf(err, "_readTransaction: Problem reading TxnMeta") 2516 } 2517 err = ret.TxnMeta.FromBytes(metaBuf) 2518 if err != nil { 2519 return nil, errors.Wrapf(err, "_readTransaction: Problem decoding TxnMeta: ") 2520 } 2521 2522 // De-serialize the public key if there is one 2523 pkLen, err := ReadUvarint(rr) 2524 if err != nil { 2525 return nil, errors.Wrapf(err, "_readTransaction: Problem reading len(DeSoTxn.PublicKey)") 2526 } 2527 if pkLen > MaxMessagePayload { 2528 return nil, fmt.Errorf("_readTransaction.FromBytes: pkLen length %d longer than max %d", pkLen, MaxMessagePayload) 2529 } 2530 ret.PublicKey = nil 2531 if pkLen != 0 { 2532 ret.PublicKey = make([]byte, pkLen) 2533 _, err = io.ReadFull(rr, ret.PublicKey) 2534 if err != nil { 2535 return nil, errors.Wrapf(err, "_readTransaction: Problem reading DeSoTxn.PublicKey") 2536 } 2537 } 2538 2539 // De-serialize the ExtraData 2540 extraDataLen, err := ReadUvarint(rr) 2541 if err != nil { 2542 return nil, errors.Wrapf(err, "_readTransaction: Problem reading len(DeSoTxn.ExtraData)") 2543 } 2544 if extraDataLen > MaxMessagePayload { 2545 return nil, fmt.Errorf("_readTransaction.FromBytes: extraDataLen length %d longer than max %d", extraDataLen, MaxMessagePayload) 2546 } 2547 // Initialize an map of strings to byte slices of size extraDataLen -- extraDataLen is the number of keys. 2548 if extraDataLen != 0 { 2549 ret.ExtraData = make(map[string][]byte, extraDataLen) 2550 // Loop over each key 2551 for ii := uint64(0); ii < extraDataLen; ii++ { 2552 // De-serialize the length of the key 2553 var keyLen uint64 2554 keyLen, err = ReadUvarint(rr) 2555 if err != nil { 2556 return nil, fmt.Errorf("_readTransaction.FromBytes: Problem reading len(DeSoTxn.ExtraData.Keys[#{ii}]") 2557 } 2558 // De-serialize the key 2559 keyBytes := make([]byte, keyLen) 2560 _, err = io.ReadFull(rr, keyBytes) 2561 if err != nil { 2562 return nil, fmt.Errorf("_readTransaction.FromBytes: Problem reading key #{ii}") 2563 } 2564 // Convert the key to a string and check if it already exists in the map. 2565 // If it already exists in the map, this is an error as a map cannot have duplicate keys. 2566 key := string(keyBytes) 2567 if _, keyExists := ret.ExtraData[key]; keyExists { 2568 return nil, fmt.Errorf("_readTransaction.FromBytes: Key [#{ii}] ({key}) already exists in ExtraData") 2569 } 2570 // De-serialize the length of the value 2571 var valueLen uint64 2572 valueLen, err = ReadUvarint(rr) 2573 if err != nil { 2574 return nil, fmt.Errorf("_readTransaction.FromBytes: Problem reading len(DeSoTxn.ExtraData.Value[#{ii}]") 2575 } 2576 // De-serialize the value 2577 value := make([]byte, valueLen) 2578 _, err = io.ReadFull(rr, value) 2579 if err != nil { 2580 return nil, fmt.Errorf("_readTransaction.FromBytes: Problem read value #{ii}") 2581 } 2582 // Map the key to the value 2583 ret.ExtraData[key] = value 2584 } 2585 } 2586 2587 // De-serialize the signature if there is one. 2588 sigLen, err := ReadUvarint(rr) 2589 if err != nil { 2590 return nil, errors.Wrapf(err, "_readTransaction: Problem reading len(DeSoTxn.Signature)") 2591 } 2592 if sigLen > MaxMessagePayload { 2593 return nil, fmt.Errorf("_readTransaction.FromBytes: sigLen length %d longer than max %d", sigLen, MaxMessagePayload) 2594 } 2595 2596 ret.Signature = nil 2597 if sigLen != 0 { 2598 sigBytes := make([]byte, sigLen) 2599 _, err = io.ReadFull(rr, sigBytes) 2600 if err != nil { 2601 return nil, errors.Wrapf(err, "_readTransaction: Problem reading DeSoTxn.Signature") 2602 } 2603 2604 // Verify that the signature is valid. 2605 sig, err := btcec.ParseDERSignature(sigBytes, btcec.S256()) 2606 if err != nil { 2607 return nil, errors.Wrapf(err, "_readTransaction: Problem parsing DeSoTxn.Signature bytes") 2608 } 2609 // If everything worked, we set the ret signature to the original. 2610 ret.Signature = sig 2611 } 2612 2613 return ret, nil 2614 } 2615 2616 func (msg *MsgDeSoTxn) FromBytes(data []byte) error { 2617 rr := bytes.NewReader(data) 2618 2619 ret, err := _readTransaction(rr) 2620 if err != nil { 2621 return errors.Wrapf(err, "MsgDeSoTxn.FromBytes: Problem reading txn: ") 2622 } 2623 *msg = *ret 2624 return nil 2625 } 2626 2627 func (msg *MsgDeSoTxn) GetMsgType() MsgType { 2628 return MsgTypeTxn 2629 } 2630 2631 // Hash is a helper function to compute a hash of the transaction aka a 2632 // transaction ID. 2633 func (msg *MsgDeSoTxn) Hash() *BlockHash { 2634 // BitcoinExchange transactions are a special case whereby the hash 2635 // of the DeSo transaction is defined as the hash of the Bitcoin 2636 // transaction embedded within it. This allows us to use BitcoinExchange 2637 // transactions as inputs to subsequent transactions *before* the 2638 // merkle proof has actually been defined. Thus it allows us to support 2639 // the "instant DeSo buy" feature in the UI. 2640 if msg.TxnMeta.GetTxnType() == TxnTypeBitcoinExchange { 2641 bitcoinTxHash := (BlockHash)( 2642 msg.TxnMeta.(*BitcoinExchangeMetadata).BitcoinTransaction.TxHash()) 2643 return &bitcoinTxHash 2644 } 2645 2646 preSignature := false 2647 txBytes, err := msg.ToBytes(preSignature) 2648 if err != nil { 2649 return nil 2650 } 2651 2652 return Sha256DoubleHash(txBytes) 2653 } 2654 2655 func (msg *MsgDeSoTxn) Copy() (*MsgDeSoTxn, error) { 2656 txnBytes, err := msg.ToBytes(false /*preSignature*/) 2657 if err != nil { 2658 return nil, errors.Wrapf(err, "MsgDeSoTxn.Copy: ") 2659 } 2660 newTxn := &MsgDeSoTxn{} 2661 err = newTxn.FromBytes(txnBytes) 2662 if err != nil { 2663 return nil, errors.Wrapf(err, "MsgDeSoTxn.Copy: ") 2664 } 2665 return newTxn, nil 2666 } 2667 2668 func (msg *MsgDeSoTxn) Sign(privKey *btcec.PrivateKey) (*btcec.Signature, error) { 2669 // Serialize the transaction without the signature portion. 2670 txnBytes, err := msg.ToBytes(true /*preSignature*/) 2671 if err != nil { 2672 return nil, err 2673 } 2674 // Compute a hash of the transaction bytes without the signature 2675 // portion and sign it with the passed private key. 2676 txnSignatureHash := Sha256DoubleHash(txnBytes) 2677 txnSignature, err := privKey.Sign(txnSignatureHash[:]) 2678 if err != nil { 2679 return nil, err 2680 } 2681 return txnSignature, nil 2682 } 2683 2684 // SignTransactionWithDerivedKey the signature contains solution iteration, 2685 // which allows us to recover signer public key from the signature. 2686 // Returns (new txn bytes, txn signature, error) 2687 func SignTransactionWithDerivedKey(txnBytes []byte, privateKey *btcec.PrivateKey) ([]byte, []byte, error) { 2688 // As we're signing the transaction using a derived key, we 2689 // pass the key to extraData. 2690 rr := bytes.NewReader(txnBytes) 2691 txn, err := _readTransaction(rr) 2692 if err != nil { 2693 return nil, nil, errors.Wrapf(err, "SignTransactionWithDerivedKey: Problem reading txn: ") 2694 } 2695 if txn.ExtraData == nil { 2696 txn.ExtraData = make(map[string][]byte) 2697 } 2698 txn.ExtraData[DerivedPublicKey] = privateKey.PubKey().SerializeCompressed() 2699 2700 // Sign the transaction with the passed private key. 2701 txnSignature, err := txn.Sign(privateKey) 2702 if err != nil { 2703 return nil, nil, err 2704 } 2705 2706 newTxnBytes, err := txn.ToBytes(true) 2707 if err != nil { 2708 return nil, nil, err 2709 } 2710 2711 return newTxnBytes, txnSignature.Serialize(), nil 2712 } 2713 2714 // MarshalJSON and UnmarshalJSON implement custom JSON marshaling/unmarshaling 2715 // to support transaction metadata. The reason this needs to exist is because 2716 // TxnMeta is an abstract interface and therefore 2717 // when its decoded to JSON, the type information (i.e. which TxnType it is) 2718 // cannot be inferred from the JSON unless we augment it a little bit. 2719 // Note this format is not used to relay messages between nodes, only 2720 // for replying to frontend/user-facing queries. 2721 func (msg *MsgDeSoTxn) MarshalJSON() ([]byte, error) { 2722 // Copy the txn so none of the fields get set on the passed-in txn. 2723 txnCopy := *msg 2724 // If there's no metadata then we have an error. Transactions should 2725 // always have a metadata field that indicates what type the transaction 2726 // is. 2727 if txnCopy.TxnMeta == nil { 2728 return nil, fmt.Errorf("MsgDeSoTxn.MarshalJSON: Transaction is missing TxnMeta: %v", txnCopy) 2729 } 2730 // Set the txnType based on the metadata that is set. 2731 txnCopy.TxnTypeJSON = uint64(txnCopy.TxnMeta.GetTxnType()) 2732 return json.Marshal(txnCopy) 2733 } 2734 2735 // UnmarshalJSON is covered by the comment on MarshalJSON. 2736 func (msg *MsgDeSoTxn) UnmarshalJSON(data []byte) error { 2737 // Use the map-based JSON conversion to determine the type of the 2738 // TxnMeta and initialize it appropriately. 2739 var responseMap map[string]interface{} 2740 err := json.Unmarshal(data, &responseMap) 2741 if err != nil { 2742 return err 2743 } 2744 2745 // Set the TxnMeta based on the TxnType that's set in the top level 2746 // of the transaction. 2747 txnType, txnTypeExists := responseMap["TxnTypeJSON"] 2748 if !txnTypeExists { 2749 // If there is not metadata that's an error. 2750 return fmt.Errorf("MsgDeSoTxn.UnmarshalJSON: Field txnType is missing "+ 2751 "from JSON decoded map: %v", responseMap) 2752 } 2753 txnMeta, err := NewTxnMetadata(TxnType(uint64(txnType.(float64)))) 2754 if err != nil { 2755 return fmt.Errorf("MsgDeSoTxn.UnmarshalJSON: Problem parsing TxnType: %v, %v", err, responseMap) 2756 } 2757 msg.TxnMeta = txnMeta 2758 2759 // TODO: The code below is an ugly hack, but it achieves the goal of making 2760 // TxnMeta (and MsgDeSoTxn by proxy) serializable to JSON without any extra overhead 2761 // needed on the caller side. This is particularly important when one considers 2762 // that transactions can be serialized to JSON as part of blocks, 2763 // and this makes it so that even in that case no special handling is 2764 // needed by the code serializing/deserializing, which is good. Still, would 2765 // be nice if, for example, the code below didn't break whenever we modify 2766 // MsgDeSoTxn (which is admittedly very rare and a test can easily catch this 2767 // by erroring when the number of fields changes with a helpful message). 2768 anonymousTxn := struct { 2769 TxInputs []*DeSoInput 2770 TxOutputs []*DeSoOutput 2771 TxnMeta DeSoTxnMetadata 2772 PublicKey []byte 2773 Signature *btcec.Signature 2774 TxnType uint64 2775 }{ 2776 TxInputs: msg.TxInputs, 2777 TxOutputs: msg.TxOutputs, 2778 TxnMeta: msg.TxnMeta, 2779 PublicKey: msg.PublicKey, 2780 Signature: msg.Signature, 2781 TxnType: msg.TxnTypeJSON, 2782 } 2783 json.Unmarshal(data, &anonymousTxn) 2784 2785 msg.TxInputs = anonymousTxn.TxInputs 2786 msg.TxOutputs = anonymousTxn.TxOutputs 2787 msg.TxnMeta = anonymousTxn.TxnMeta 2788 msg.PublicKey = anonymousTxn.PublicKey 2789 msg.Signature = anonymousTxn.Signature 2790 // Don't set the TxnTypeJSON when unmarshaling. It should never be used in 2791 // Go code, only at the interface between Go and non-Go. 2792 msg.TxnTypeJSON = 0 2793 2794 return nil 2795 } 2796 2797 // ================================================================== 2798 // BasicTransferMetadata 2799 // ================================================================== 2800 2801 type BasicTransferMetadata struct { 2802 // Requires no extra information 2803 } 2804 2805 func (txnData *BasicTransferMetadata) GetTxnType() TxnType { 2806 return TxnTypeBasicTransfer 2807 } 2808 2809 func (txnData *BasicTransferMetadata) ToBytes(preSignature bool) ([]byte, error) { 2810 return []byte{}, nil 2811 } 2812 2813 func (txnData *BasicTransferMetadata) FromBytes(data []byte) error { 2814 // Nothing to set 2815 return nil 2816 } 2817 2818 func (txnData *BasicTransferMetadata) New() DeSoTxnMetadata { 2819 return &BasicTransferMetadata{} 2820 } 2821 2822 // ================================================================== 2823 // BlockRewardMetadataa 2824 // ================================================================== 2825 2826 type BlockRewardMetadataa struct { 2827 // A block reward txn has an ExtraData field that can be between 2828 // zero and 100 bytes long. It can theoretically contain anything 2829 // but in practice it's likely that miners will use this field to 2830 // update the merkle root of the block, which may make the block 2831 // easier to mine (namely by allowing the Nonce in the header to 2832 // be shorter). 2833 ExtraData []byte 2834 } 2835 2836 func (txnData *BlockRewardMetadataa) GetTxnType() TxnType { 2837 return TxnTypeBlockReward 2838 } 2839 2840 func (txnData *BlockRewardMetadataa) ToBytes(preSignature bool) ([]byte, error) { 2841 retBytes := []byte{} 2842 2843 // ExtraData. 2844 numExtraDataBytes := len(txnData.ExtraData) 2845 if numExtraDataBytes > MaxBlockRewardDataSizeBytes { 2846 return nil, fmt.Errorf( 2847 "BLOCK_REWARD txn ExtraData length (%d) cannot be longer than "+ 2848 "(%d) bytes", numExtraDataBytes, MaxBlockRewardDataSizeBytes) 2849 } 2850 retBytes = append(retBytes, UintToBuf(uint64(numExtraDataBytes))...) 2851 retBytes = append(retBytes, txnData.ExtraData...) 2852 2853 return retBytes, nil 2854 } 2855 2856 func (txnData *BlockRewardMetadataa) FromBytes(dataa []byte) error { 2857 ret := BlockRewardMetadataa{} 2858 rr := bytes.NewReader(dataa) 2859 2860 // ExtraData 2861 numExtraDataBytes, err := ReadUvarint(rr) 2862 if err != nil { 2863 return errors.Wrapf(err, "BlockRewardMetadataa.FromBytes: Problem reading NumExtraDataBytes") 2864 } 2865 2866 if numExtraDataBytes > uint64(MaxBlockRewardDataSizeBytes) { 2867 return fmt.Errorf( 2868 "BLOCK_REWARD txn ExtraData length (%d) cannot be longer than "+ 2869 "(%d) bytes", numExtraDataBytes, MaxBlockRewardDataSizeBytes) 2870 } 2871 ret.ExtraData = make([]byte, numExtraDataBytes) 2872 _, err = io.ReadFull(rr, ret.ExtraData[:]) 2873 if err != nil { 2874 return errors.Wrapf(err, "BlockRewardMetadataa.FromBytes: Problem reading ExtraData") 2875 } 2876 2877 *txnData = ret 2878 return nil 2879 } 2880 2881 func (txnData *BlockRewardMetadataa) New() DeSoTxnMetadata { 2882 return &BlockRewardMetadataa{} 2883 } 2884 2885 func EncryptBytesWithPublicKey(bytesToEncrypt []byte, pubkey *ecdsa.PublicKey) ([]byte, error) { 2886 eciesPubkey := ecies.ImportECDSAPublic(pubkey) 2887 // Note we need to manually set the Params. Params is normally 2888 // set automatically in ImportECDSA based on what curve you're using. 2889 // However, because we use btcec.S256() rather than Ethereum's 2890 // implementation ethcrypto.S256(), which is just a wrapper around 2891 // secp256k1, the ecies library fails to fetch the proper parameters 2892 // for our curve even though it is functionally identical. So we just 2893 // set the params here and everything works. 2894 eciesPubkey.Params = ecies.ECIES_AES128_SHA256 2895 return ecies.Encrypt(rand.Reader, eciesPubkey, bytesToEncrypt, nil, nil) 2896 } 2897 2898 func DecryptBytesWithPrivateKey(bytesToDecrypt []byte, privKey *ecdsa.PrivateKey) ([]byte, error) { 2899 eciesKeypair := ecies.ImportECDSA(privKey) 2900 // Note we need to manually set the Params. Params is normally 2901 // set automatically in ImportECDSA based on what curve you're using. 2902 // However, because we use btcec.S256() rather than Ethereum's 2903 // implementation ethcrypto.S256(), which is just a wrapper around 2904 // secp256k1, the ecies library fails to fetch the proper parameters 2905 // for our curve even though it is functionally identical. So we just 2906 // set the params here and everything works. 2907 eciesKeypair.Params = ecies.ECIES_AES128_SHA256 2908 return eciesKeypair.Decrypt(bytesToDecrypt, nil, nil) 2909 } 2910 2911 // ================================================================== 2912 // BitcoinExchangeMetadata 2913 // ================================================================== 2914 2915 type BitcoinExchangeMetadata struct { 2916 // The Bitcoin transaction that sends Bitcoin to the designated burn address. 2917 BitcoinTransaction *wire.MsgTx 2918 // The hash of the Bitcoin block in which the Bitcoin transaction was mined. 2919 BitcoinBlockHash *BlockHash 2920 // The Bitcoin mekle root corresponding to the block in which the BitcoinTransaction 2921 // above was mined. Note that it is not strictly necessary to include this field 2922 // since we can look it up from the Bitcoin header if we know the BitcoinBlockHash. 2923 // However, having it here is convenient and allows us to do more validation prior 2924 // to looking up the header in the Bitcoin header chain. 2925 BitcoinMerkleRoot *BlockHash 2926 // This is a merkle proof that shows that the BitcoinTransaction above, with 2927 // hash equal to BitcoinTransactionHash, exists in the block with hash equal 2928 // to BitcoinBlockHash. This is effectively a path through a Merkle tree starting 2929 // from BitcoinTransactionHash as a leaf node and finishing with BitcoinMerkleRoot 2930 // as the root. 2931 BitcoinMerkleProof []*merkletree.ProofPart 2932 } 2933 2934 func (txnData *BitcoinExchangeMetadata) GetTxnType() TxnType { 2935 return TxnTypeBitcoinExchange 2936 } 2937 2938 func (txnData *BitcoinExchangeMetadata) ToBytes(preSignature bool) ([]byte, error) { 2939 data := []byte{} 2940 2941 // BitcoinTransaction 2942 txnBytes := bytes.Buffer{} 2943 if err := txnData.BitcoinTransaction.Serialize(&txnBytes); err != nil { 2944 return nil, errors.Wrapf(err, "BitcoinExchangeMetadata.ToBytes: Problem "+ 2945 "serializing BitcoinTransaction: ") 2946 } 2947 data = append(data, UintToBuf(uint64(len(txnBytes.Bytes())))...) 2948 data = append(data, txnBytes.Bytes()...) 2949 2950 // BitcoinBlockHash 2951 data = append(data, txnData.BitcoinBlockHash[:]...) 2952 2953 // BitcoinMerkleRoot 2954 data = append(data, txnData.BitcoinMerkleRoot[:]...) 2955 2956 // BitcoinMerkleProof 2957 // 2958 // Encode the number of proof parts followed by all the proof parts. 2959 numProofParts := uint64(len(txnData.BitcoinMerkleProof)) 2960 data = append(data, UintToBuf(numProofParts)...) 2961 for _, pf := range txnData.BitcoinMerkleProof { 2962 // ProofParts have a specific length so no need to encode the length. 2963 pfBytes, err := pf.Serialize() 2964 if err != nil { 2965 return nil, errors.Wrapf(err, "BitcoinExchangeMetadata.ToBytes") 2966 } 2967 2968 data = append(data, pfBytes...) 2969 } 2970 2971 return data, nil 2972 } 2973 2974 func (txnData *BitcoinExchangeMetadata) FromBytes(data []byte) error { 2975 ret := BitcoinExchangeMetadata{} 2976 rr := bytes.NewReader(data) 2977 2978 // BitcoinTransaction 2979 txnBytesLen, err := ReadUvarint(rr) 2980 if err != nil { 2981 return errors.Wrapf(err, "BitcoinExchangeMetadata.FromBytes: Problem "+ 2982 "decoding BitcoinTransaction length") 2983 } 2984 if txnBytesLen > MaxMessagePayload { 2985 return fmt.Errorf("BitcoinExchangeMetadata.FromBytes: txnBytesLen %d "+ 2986 "exceeds max %d", txnBytesLen, MaxMessagePayload) 2987 } 2988 txnBytes := make([]byte, txnBytesLen) 2989 _, err = io.ReadFull(rr, txnBytes) 2990 if err != nil { 2991 return fmt.Errorf("BitcoinExchangeMetadata.FromBytes: Error reading txnBytes: %v", err) 2992 } 2993 ret.BitcoinTransaction = &wire.MsgTx{} 2994 err = ret.BitcoinTransaction.Deserialize(bytes.NewBuffer(txnBytes)) 2995 if err != nil { 2996 return errors.Wrapf(err, "BitcoinExchangeMetadata.FromBytes: Problem parsing txnBytes: ") 2997 } 2998 2999 // BitcoinBlockHash 3000 ret.BitcoinBlockHash = &BlockHash{} 3001 _, err = io.ReadFull(rr, ret.BitcoinBlockHash[:]) 3002 if err != nil { 3003 return errors.Wrapf(err, "BitcoinExchangeMetadata.FromBytes: Problem reading BitcoinBlockHash: ") 3004 } 3005 3006 // BitcoinMerkleRoot 3007 ret.BitcoinMerkleRoot = &BlockHash{} 3008 _, err = io.ReadFull(rr, ret.BitcoinMerkleRoot[:]) 3009 if err != nil { 3010 return errors.Wrapf(err, "BitcoinExchangeMetadata.FromBytes: Problem reading BitcoinMerkleRoot: ") 3011 } 3012 3013 // BitcoinMerkleProof 3014 numProofParts, err := ReadUvarint(rr) 3015 if err != nil { 3016 return errors.Wrapf(err, "BitcoinExchangeMetadata.FromBytes: Problem reading numProofParts: ") 3017 } 3018 for ii := uint64(0); ii < numProofParts; ii++ { 3019 pfBytes := make([]byte, merkletree.ProofPartSerializeSize) 3020 _, err = io.ReadFull(rr, pfBytes[:]) 3021 if err != nil { 3022 return errors.Wrapf(err, "BitcoinExchangeMetadata.FromBytes: Problem reading ProofPart %d: ", ii) 3023 } 3024 pf := &merkletree.ProofPart{} 3025 if err := pf.Deserialize(pfBytes); err != nil { 3026 return errors.Wrapf(err, "BitcoinExchangeMetadata.FromBytes: Problem parsing ProofPart %d: ", ii) 3027 } 3028 3029 ret.BitcoinMerkleProof = append(ret.BitcoinMerkleProof, pf) 3030 } 3031 3032 *txnData = ret 3033 3034 return nil 3035 } 3036 3037 func (txnData *BitcoinExchangeMetadata) New() DeSoTxnMetadata { 3038 return &BitcoinExchangeMetadata{} 3039 } 3040 3041 // ================================================================== 3042 // PrivateMessageMetadata 3043 // 3044 // A private message is a message from one user on the platform to 3045 // another user on the platform. It is generally treated as a normal 3046 // transaction would be except that the public key of the top-level 3047 // MsgDeSoTxn is assumed to be the sender of the message and the 3048 // metadata contains a messange encrypted with the receiver's public 3049 // key. 3050 // ================================================================== 3051 3052 type PrivateMessageMetadata struct { 3053 // The sender of the message is assumed to be the originator of the 3054 // top-level transaction. 3055 3056 // The public key of the recipient of the message. 3057 RecipientPublicKey []byte 3058 3059 // The content of the message. It is encrypted with the recipient's 3060 // public key using ECIES. 3061 EncryptedText []byte 3062 3063 // A timestamp used for ordering messages when displaying them to 3064 // users. The timestamp must be unique. Note that we use a nanosecond 3065 // timestamp because it makes it easier to deal with the uniqueness 3066 // constraint technically (e.g. If one second spacing is required 3067 // as would be the case with a standard Unix timestamp then any code 3068 // that generates these transactions will need to potentially wait 3069 // or else risk a timestamp collision. This complexity is avoided 3070 // by just using a nanosecond timestamp). Note that the timestamp is 3071 // an unsigned int as opposed to a signed int, which means times 3072 // before the zero time are not represented which doesn't matter 3073 // for our purposes. Restricting the timestamp in this way makes 3074 // lexicographic sorting based on bytes easier in our database which 3075 // is one of the reasons we do it. 3076 TimestampNanos uint64 3077 } 3078 3079 func (txnData *PrivateMessageMetadata) GetTxnType() TxnType { 3080 return TxnTypePrivateMessage 3081 } 3082 3083 func (txnData *PrivateMessageMetadata) ToBytes(preSignature bool) ([]byte, error) { 3084 // Validate the metadata before encoding it. 3085 // 3086 // Public key must be included and must have the expected length. 3087 if len(txnData.RecipientPublicKey) != btcec.PubKeyBytesLenCompressed { 3088 return nil, fmt.Errorf("PrivateMessageMetadata.ToBytes: RecipientPublicKey "+ 3089 "has length %d != %d", len(txnData.RecipientPublicKey), btcec.PubKeyBytesLenCompressed) 3090 } 3091 3092 data := []byte{} 3093 3094 // RecipientPublicKey 3095 // 3096 // We know the public key is set and has the expected length so we don't need 3097 // to encode the length here. 3098 data = append(data, txnData.RecipientPublicKey...) 3099 3100 // EncryptedText 3101 data = append(data, UintToBuf(uint64(len(txnData.EncryptedText)))...) 3102 data = append(data, txnData.EncryptedText...) 3103 3104 // TimestampNanos 3105 data = append(data, UintToBuf(txnData.TimestampNanos)...) 3106 3107 return data, nil 3108 } 3109 3110 func (txnData *PrivateMessageMetadata) FromBytes(data []byte) error { 3111 ret := PrivateMessageMetadata{} 3112 rr := bytes.NewReader(data) 3113 3114 // RecipientPublicKey 3115 ret.RecipientPublicKey = make([]byte, btcec.PubKeyBytesLenCompressed) 3116 _, err := io.ReadFull(rr, ret.RecipientPublicKey) 3117 if err != nil { 3118 return fmt.Errorf("PrivateMessageMetadata.FromBytes: Error reading RecipientPublicKey: %v", err) 3119 } 3120 3121 // EncryptedText 3122 encryptedTextLen, err := ReadUvarint(rr) 3123 if err != nil { 3124 return errors.Wrapf(err, "PrivateMessageMetadata.FromBytes: Problem "+ 3125 "decoding EncryptedText length") 3126 } 3127 if encryptedTextLen > MaxMessagePayload { 3128 return fmt.Errorf("PrivateMessageMetadata.FromBytes: encryptedTextLen %d "+ 3129 "exceeds max %d", encryptedTextLen, MaxMessagePayload) 3130 } 3131 ret.EncryptedText = make([]byte, encryptedTextLen) 3132 _, err = io.ReadFull(rr, ret.EncryptedText) 3133 if err != nil { 3134 return fmt.Errorf("PrivateMessageMetadata.FromBytes: Error reading EncryptedText: %v", err) 3135 } 3136 3137 // TimestampNanos 3138 ret.TimestampNanos, err = ReadUvarint(rr) 3139 if err != nil { 3140 return fmt.Errorf("PrivateMessageMetadata.FromBytes: Error reading TimestampNanos: %v", err) 3141 } 3142 3143 *txnData = ret 3144 3145 return nil 3146 } 3147 3148 func (txnData *PrivateMessageMetadata) New() DeSoTxnMetadata { 3149 return &PrivateMessageMetadata{} 3150 } 3151 3152 // ================================================================== 3153 // LikeMetadata 3154 // 3155 // A like is an interaction where a user on the platform "likes" a post. 3156 // ================================================================== 3157 3158 type LikeMetadata struct { 3159 // The user casting a "like" is assumed to be the originator of the 3160 // top-level transaction. 3161 3162 // The post hash to like. 3163 LikedPostHash *BlockHash 3164 3165 // Set to true when a user is requesting to unlike a post. 3166 IsUnlike bool 3167 } 3168 3169 func (txnData *LikeMetadata) GetTxnType() TxnType { 3170 return TxnTypeLike 3171 } 3172 3173 func (txnData *LikeMetadata) ToBytes(preSignature bool) ([]byte, error) { 3174 // Validate the metadata before encoding it. 3175 // 3176 // Post hash must be included and must have the expected length. 3177 if len(txnData.LikedPostHash) != HashSizeBytes { 3178 return nil, fmt.Errorf("LikeMetadata.ToBytes: LikedPostHash "+ 3179 "has length %d != %d", len(txnData.LikedPostHash), HashSizeBytes) 3180 } 3181 3182 data := []byte{} 3183 3184 // Add LikedPostHash 3185 // 3186 // We know the post hash is set and has the expected length so we don't need 3187 // to encode the length here. 3188 data = append(data, txnData.LikedPostHash[:]...) 3189 3190 // Add IsUnlike bool. 3191 data = append(data, BoolToByte(txnData.IsUnlike)) 3192 3193 return data, nil 3194 } 3195 3196 func (txnData *LikeMetadata) FromBytes(data []byte) error { 3197 ret := LikeMetadata{} 3198 rr := bytes.NewReader(data) 3199 3200 // LikedPostHash 3201 ret.LikedPostHash = &BlockHash{} 3202 _, err := io.ReadFull(rr, ret.LikedPostHash[:]) 3203 if err != nil { 3204 return fmt.Errorf( 3205 "LikeMetadata.FromBytes: Error reading LikedPostHash: %v", err) 3206 } 3207 3208 // IsUnlike 3209 ret.IsUnlike = ReadBoolByte(rr) 3210 3211 *txnData = ret 3212 3213 return nil 3214 } 3215 3216 func (txnData *LikeMetadata) New() DeSoTxnMetadata { 3217 return &LikeMetadata{} 3218 } 3219 3220 // ================================================================== 3221 // FollowMetadata 3222 // 3223 // A follow is an interaction where one user on the platform 3224 // "follows" another user on the platform. This is used as an 3225 // indicator to UIs/Feeds that a user is interested in 3226 // consuming the "followed" users content. 3227 // ================================================================== 3228 3229 type FollowMetadata struct { 3230 // The follower is assumed to be the originator of the 3231 // top-level transaction. 3232 3233 // The public key to follow. 3234 FollowedPublicKey []byte 3235 3236 // Set to true when a user is requesting to unfollow. 3237 IsUnfollow bool 3238 } 3239 3240 func (txnData *FollowMetadata) GetTxnType() TxnType { 3241 return TxnTypeFollow 3242 } 3243 3244 func (txnData *FollowMetadata) ToBytes(preSignature bool) ([]byte, error) { 3245 // Validate the metadata before encoding it. 3246 // 3247 // Public key must be included and must have the expected length. 3248 if len(txnData.FollowedPublicKey) != btcec.PubKeyBytesLenCompressed { 3249 return nil, fmt.Errorf("FollowMetadata.ToBytes: FollowedPublicKey "+ 3250 "has length %d != %d", len(txnData.FollowedPublicKey), 3251 btcec.PubKeyBytesLenCompressed) 3252 } 3253 3254 data := []byte{} 3255 3256 // RecipientPublicKey 3257 // 3258 // We know the public key is set and has the expected length so we don't need 3259 // to encode the length here. 3260 data = append(data, txnData.FollowedPublicKey...) 3261 3262 // Add IsUnfollow bool. 3263 data = append(data, BoolToByte(txnData.IsUnfollow)) 3264 3265 return data, nil 3266 } 3267 3268 func (txnData *FollowMetadata) FromBytes(data []byte) error { 3269 ret := FollowMetadata{} 3270 rr := bytes.NewReader(data) 3271 3272 // FollowedPublicKey 3273 ret.FollowedPublicKey = make([]byte, btcec.PubKeyBytesLenCompressed) 3274 _, err := io.ReadFull(rr, ret.FollowedPublicKey) 3275 if err != nil { 3276 return fmt.Errorf( 3277 "FollowMetadata.FromBytes: Error reading FollowedPublicKey: %v", err) 3278 } 3279 3280 // IsUnfollow 3281 ret.IsUnfollow = ReadBoolByte(rr) 3282 3283 *txnData = ret 3284 3285 return nil 3286 } 3287 3288 func (txnData *FollowMetadata) New() DeSoTxnMetadata { 3289 return &FollowMetadata{} 3290 } 3291 3292 // = = = = = = = = = = = = = = = = = = = = = = = 3293 // DeSo 3294 // = = = = = = = = = = = = = = = = = = = = = = = 3295 3296 // ================================================================== 3297 // SubmitPostMetadata 3298 // ================================================================== 3299 3300 func ReadBoolByte(rr *bytes.Reader) bool { 3301 boolByte, err := rr.ReadByte() 3302 if err != nil { 3303 return false 3304 } 3305 if boolByte != 0 { 3306 return true 3307 } 3308 return false 3309 } 3310 3311 func BoolToByte(val bool) byte { 3312 if val { 3313 return 1 3314 } 3315 return 0 3316 } 3317 3318 type SubmitPostMetadata struct { 3319 // The creator of the post is assumed to be the originator of the 3320 // top-level transaction. 3321 3322 // When set, this transaction is treated as modifying an existing 3323 // post rather than creating a new post. 3324 PostHashToModify []byte 3325 3326 // When a ParentStakeID is set, the post is actually a comment on 3327 // another entity (either a post or a profile depending on the 3328 // type of StakeID provided). 3329 ParentStakeID []byte 3330 Body []byte 3331 3332 // The amount the creator of the post gets when someone stakes 3333 // to the post. 3334 CreatorBasisPoints uint64 3335 // The multiple of the payout when a user stakes to a post. 3336 // 2x multiple = 200% = 20,000bps 3337 StakeMultipleBasisPoints uint64 3338 3339 // A timestamp used for ordering messages when displaying them to 3340 // users. The timestamp must be unique. Note that we use a nanosecond 3341 // timestamp because it makes it easier to deal with the uniqueness 3342 // constraint technically (e.g. If one second spacing is required 3343 // as would be the case with a standard Unix timestamp then any code 3344 // that generates these transactions will need to potentially wait 3345 // or else risk a timestamp collision. This complexity is avoided 3346 // by just using a nanosecond timestamp). Note that the timestamp is 3347 // an unsigned int as opposed to a signed int, which means times 3348 // before the zero time are not represented which doesn't matter 3349 // for our purposes. Restricting the timestamp in this way makes 3350 // lexicographic sorting based on bytes easier in our database which 3351 // is one of the reasons we do it. 3352 TimestampNanos uint64 3353 3354 // When set to true, indicates that the post should be deleted. This 3355 // value is only considered when PostHashToModify is set to a valid 3356 // pre-existing post. 3357 IsHidden bool 3358 } 3359 3360 func (txnData *SubmitPostMetadata) GetTxnType() TxnType { 3361 return TxnTypeSubmitPost 3362 } 3363 3364 func (txnData *SubmitPostMetadata) ToBytes(preSignature bool) ([]byte, error) { 3365 data := []byte{} 3366 3367 // PostHashToModify 3368 data = append(data, UintToBuf(uint64(len(txnData.PostHashToModify)))...) 3369 data = append(data, txnData.PostHashToModify...) 3370 3371 // ParentPostHash 3372 data = append(data, UintToBuf(uint64(len(txnData.ParentStakeID)))...) 3373 data = append(data, txnData.ParentStakeID...) 3374 3375 // Body 3376 data = append(data, UintToBuf(uint64(len(txnData.Body)))...) 3377 data = append(data, txnData.Body...) 3378 3379 // CreatorBasisPoints 3380 data = append(data, UintToBuf(txnData.CreatorBasisPoints)...) 3381 3382 // StakeMultipleBasisPoints 3383 data = append(data, UintToBuf(txnData.StakeMultipleBasisPoints)...) 3384 3385 // TimestampNanos 3386 data = append(data, UintToBuf(txnData.TimestampNanos)...) 3387 3388 // IsHidden 3389 data = append(data, BoolToByte(txnData.IsHidden)) 3390 3391 return data, nil 3392 } 3393 3394 func ReadVarString(rr io.Reader) ([]byte, error) { 3395 StringLen, err := ReadUvarint(rr) 3396 if err != nil { 3397 return nil, errors.Wrapf(err, "SubmitPostMetadata.FromBytes: Problem "+ 3398 "decoding String length") 3399 } 3400 if StringLen > MaxMessagePayload { 3401 return nil, fmt.Errorf("SubmitPostMetadata.FromBytes: StringLen %d "+ 3402 "exceeds max %d", StringLen, MaxMessagePayload) 3403 } 3404 ret := make([]byte, StringLen) 3405 _, err = io.ReadFull(rr, ret) 3406 if err != nil { 3407 return nil, fmt.Errorf("SubmitPostMetadata.FromBytes: Error reading StringText: %v", err) 3408 } 3409 3410 return ret, nil 3411 } 3412 3413 func (txnData *SubmitPostMetadata) FromBytes(data []byte) error { 3414 ret := SubmitPostMetadata{} 3415 rr := bytes.NewReader(data) 3416 3417 // PostHashToModify 3418 var err error 3419 ret.PostHashToModify, err = ReadVarString(rr) 3420 if err != nil { 3421 return fmt.Errorf("SubmitPostMetadata.FromBytes: Error reading PostHashToModify: %v", err) 3422 } 3423 3424 // ParentStakeID 3425 ret.ParentStakeID, err = ReadVarString(rr) 3426 if err != nil { 3427 return fmt.Errorf("SubmitPostMetadata.FromBytes: Error reading ParentStakeID: %v", err) 3428 } 3429 3430 // Body 3431 ret.Body, err = ReadVarString(rr) 3432 if err != nil { 3433 return fmt.Errorf( 3434 "SubmitPostMetadata.FromBytes: Error reading Body: %v", err) 3435 } 3436 3437 // CreatorBasisPoints 3438 ret.CreatorBasisPoints, err = ReadUvarint(rr) 3439 if err != nil { 3440 return fmt.Errorf("SubmitPostMetadata.FromBytes: Error reading CreatorBasisPoints: %v", err) 3441 } 3442 3443 // StakeMultipleBasisPoints 3444 ret.StakeMultipleBasisPoints, err = ReadUvarint(rr) 3445 if err != nil { 3446 return fmt.Errorf("SubmitPostMetadata.FromBytes: Error reading StakeMultipleBasisPoints: %v", err) 3447 } 3448 3449 // TimestampNanos 3450 ret.TimestampNanos, err = ReadUvarint(rr) 3451 if err != nil { 3452 return fmt.Errorf("SubmitPostMetadata.FromBytes: Error reading TimestampNanos: %v", err) 3453 } 3454 3455 // IsHidden 3456 ret.IsHidden = ReadBoolByte(rr) 3457 3458 *txnData = ret 3459 3460 return nil 3461 } 3462 3463 func (txnData *SubmitPostMetadata) New() DeSoTxnMetadata { 3464 return &SubmitPostMetadata{} 3465 } 3466 3467 // ================================================================== 3468 // UpdateProfileMetadata 3469 // ================================================================== 3470 3471 type UpdateProfileMetadata struct { 3472 // The public key being updated is assumed to be the originator of the 3473 // top-level transaction. 3474 3475 // The public key of the profile to update. When left unset, the public 3476 // key in the transaction is used. 3477 ProfilePublicKey []byte 3478 3479 NewUsername []byte 3480 NewDescription []byte 3481 NewProfilePic []byte 3482 3483 // This is the percentage of each "net buy" that a creator earns when 3484 // someone purchases her coin. For example, if this were set to 25%, 3485 // then every time their coin reaches a new high, they would get 25% 3486 // of the coins as they're being minted. More concretely, if someone 3487 // put in enough DeSo to buy 10 coins, the creator would get 2.5 3488 // and this person would get 7.5. However, if they sold 5 coins and 3489 // someone subsequently bought those same coins, the creator wouldn't 3490 // get any coins because no "net new" coins have been created. 3491 NewCreatorBasisPoints uint64 3492 3493 // The multiple of the payout when a user stakes to this profile. If 3494 // unset, a sane default is set when the first person stakes to this 3495 // profile. 3496 // 2x multiple = 200% = 20,000bps 3497 // 3498 // TODO: This field is deprecated; delete it. 3499 NewStakeMultipleBasisPoints uint64 3500 3501 // Profile is hidden from the UI when this field is true. 3502 // TODO: This field is deprecated; delete it. 3503 IsHidden bool 3504 } 3505 3506 func (txnData *UpdateProfileMetadata) GetTxnType() TxnType { 3507 return TxnTypeUpdateProfile 3508 } 3509 3510 func (txnData *UpdateProfileMetadata) ToBytes(preSignature bool) ([]byte, error) { 3511 data := []byte{} 3512 3513 // ProfilePublicKey 3514 data = append(data, UintToBuf(uint64(len(txnData.ProfilePublicKey)))...) 3515 data = append(data, txnData.ProfilePublicKey...) 3516 3517 // NewUsername 3518 data = append(data, UintToBuf(uint64(len(txnData.NewUsername)))...) 3519 data = append(data, txnData.NewUsername...) 3520 3521 // NewDescription 3522 data = append(data, UintToBuf(uint64(len(txnData.NewDescription)))...) 3523 data = append(data, txnData.NewDescription...) 3524 3525 // NewProfilePic 3526 data = append(data, UintToBuf(uint64(len(txnData.NewProfilePic)))...) 3527 data = append(data, txnData.NewProfilePic...) 3528 3529 // NewCreatorBasisPoints 3530 data = append(data, UintToBuf(txnData.NewCreatorBasisPoints)...) 3531 3532 // NewStakeMultipleBasisPoints 3533 data = append(data, UintToBuf(txnData.NewStakeMultipleBasisPoints)...) 3534 3535 // IsHidden 3536 data = append(data, BoolToByte(txnData.IsHidden)) 3537 3538 return data, nil 3539 } 3540 3541 func (txnData *UpdateProfileMetadata) FromBytes(data []byte) error { 3542 ret := UpdateProfileMetadata{} 3543 rr := bytes.NewReader(data) 3544 3545 // ProfilePublicKey 3546 var err error 3547 ret.ProfilePublicKey, err = ReadVarString(rr) 3548 if err != nil { 3549 return fmt.Errorf( 3550 "UpdateProfileMetadata.FromBytes: Error reading ProfilePublicKey: %v", err) 3551 } 3552 // Set the profile public key to nil if it's not set as a convenience. 3553 if len(ret.ProfilePublicKey) == 0 { 3554 ret.ProfilePublicKey = nil 3555 } 3556 3557 // NewUsername 3558 ret.NewUsername, err = ReadVarString(rr) 3559 if err != nil { 3560 return fmt.Errorf( 3561 "UpdateProfileMetadata.FromBytes: Error reading NewUsername: %v", err) 3562 } 3563 3564 // NewDescription 3565 ret.NewDescription, err = ReadVarString(rr) 3566 if err != nil { 3567 return fmt.Errorf( 3568 "UpdateProfileMetadata.FromBytes: Error reading NewDescription: %v", err) 3569 } 3570 3571 // NewProfilePic 3572 ret.NewProfilePic, err = ReadVarString(rr) 3573 if err != nil { 3574 return fmt.Errorf( 3575 "UpdateProfileMetadata.FromBytes: Error reading NewProfilePic: %v", err) 3576 } 3577 3578 // NewCreatorBasisPoints 3579 ret.NewCreatorBasisPoints, err = ReadUvarint(rr) 3580 if err != nil { 3581 return fmt.Errorf("UpdateProfileMetadata.FromBytes: Error reading NewCreatorBasisPoints: %v", err) 3582 } 3583 3584 // NewStakeMultipleBasisPoints 3585 ret.NewStakeMultipleBasisPoints, err = ReadUvarint(rr) 3586 if err != nil { 3587 return fmt.Errorf("UpdateProfileMetadata.FromBytes: Error reading NewStakeMultipleBasisPoints: %v", err) 3588 } 3589 3590 // IsHidden 3591 ret.IsHidden = ReadBoolByte(rr) 3592 3593 *txnData = ret 3594 3595 return nil 3596 } 3597 3598 func (txnData *UpdateProfileMetadata) New() DeSoTxnMetadata { 3599 return &UpdateProfileMetadata{} 3600 } 3601 3602 // ================================================================== 3603 // UpdateGlobalParamsMetadata 3604 // ================================================================== 3605 type UpdateGlobalParamsMetadata struct { 3606 // The GlobalParamsMetadata struct is empty because all information is stored in the transaction's ExtraData 3607 } 3608 3609 func (txnData *UpdateGlobalParamsMetadata) GetTxnType() TxnType { 3610 return TxnTypeUpdateGlobalParams 3611 } 3612 3613 func (txnData *UpdateGlobalParamsMetadata) ToBytes(preSignature bool) ([]byte, error) { 3614 // All metadata is stored in extra for these transactions. 3615 retBytes := []byte{} 3616 return retBytes, nil 3617 } 3618 3619 func (txnData *UpdateGlobalParamsMetadata) FromBytes(data []byte) error { 3620 ret := UpdateGlobalParamsMetadata{} 3621 // All metadata is stored in extra for these transactions. 3622 *txnData = ret 3623 return nil 3624 } 3625 3626 func (txnData *UpdateGlobalParamsMetadata) New() DeSoTxnMetadata { 3627 return &UpdateGlobalParamsMetadata{} 3628 } 3629 3630 // ================================================================== 3631 // UpdateBitcoinUSDExchangeRateMetadataa 3632 // ================================================================== 3633 3634 type UpdateBitcoinUSDExchangeRateMetadataa struct { 3635 // The new exchange rate to set. 3636 USDCentsPerBitcoin uint64 3637 } 3638 3639 func (txnData *UpdateBitcoinUSDExchangeRateMetadataa) GetTxnType() TxnType { 3640 return TxnTypeUpdateBitcoinUSDExchangeRate 3641 } 3642 3643 func (txnData *UpdateBitcoinUSDExchangeRateMetadataa) ToBytes(preSignature bool) ([]byte, error) { 3644 retBytes := []byte{} 3645 3646 retBytes = append(retBytes, UintToBuf(uint64(txnData.USDCentsPerBitcoin))...) 3647 3648 return retBytes, nil 3649 } 3650 3651 func (txnData *UpdateBitcoinUSDExchangeRateMetadataa) FromBytes(dataa []byte) error { 3652 ret := UpdateBitcoinUSDExchangeRateMetadataa{} 3653 rr := bytes.NewReader(dataa) 3654 3655 // USDCentsPerBitcoin 3656 var err error 3657 ret.USDCentsPerBitcoin, err = ReadUvarint(rr) 3658 if err != nil { 3659 return fmt.Errorf("UpdateBitcoinUSDExchangeRateMetadata.FromBytes: Error reading USDCentsPerBitcoin: %v", err) 3660 } 3661 3662 *txnData = ret 3663 return nil 3664 } 3665 3666 func (txnData *UpdateBitcoinUSDExchangeRateMetadataa) New() DeSoTxnMetadata { 3667 return &UpdateBitcoinUSDExchangeRateMetadataa{} 3668 } 3669 3670 // ================================================================== 3671 // CreatorCoinMetadataa 3672 // ================================================================== 3673 3674 type CreatorCoinOperationType uint8 3675 3676 const ( 3677 CreatorCoinOperationTypeBuy CreatorCoinOperationType = 0 3678 CreatorCoinOperationTypeSell CreatorCoinOperationType = 1 3679 CreatorCoinOperationTypeAddDeSo CreatorCoinOperationType = 2 3680 ) 3681 3682 type CreatorCoinMetadataa struct { 3683 // ProfilePublicKey is the public key of the profile that owns the 3684 // coin the person wants to operate on. Creator coins can only be 3685 // bought and sold if a valid profile exists. 3686 ProfilePublicKey []byte 3687 3688 // OperationType specifies what the user wants to do with this 3689 // creator coin. 3690 OperationType CreatorCoinOperationType 3691 3692 // Generally, only one of these will be used depending on the OperationType 3693 // set. In a Buy transaction, DeSoToSellNanos will be converted into 3694 // creator coin on behalf of the user. In a Sell transaction, 3695 // CreatorCoinToSellNanos will be converted into DeSo. In an AddDeSo 3696 // operation, DeSoToAddNanos will be aded for the user. This allows us to 3697 // support multiple transaction types with same meta field. 3698 DeSoToSellNanos uint64 3699 CreatorCoinToSellNanos uint64 3700 DeSoToAddNanos uint64 3701 3702 // When a user converts DeSo into CreatorCoin, MinCreatorCoinExpectedNanos 3703 // specifies the minimum amount of creator coin that the user expects from their 3704 // transaction. And vice versa when a user is converting CreatorCoin for DeSo. 3705 // Specifying these fields prevents the front-running of users' buy/sell. Setting 3706 // them to zero turns off the check. Give it your best shot, Ivan. 3707 MinDeSoExpectedNanos uint64 3708 MinCreatorCoinExpectedNanos uint64 3709 } 3710 3711 func (txnData *CreatorCoinMetadataa) GetTxnType() TxnType { 3712 return TxnTypeCreatorCoin 3713 } 3714 3715 func (txnData *CreatorCoinMetadataa) ToBytes(preSignature bool) ([]byte, error) { 3716 data := []byte{} 3717 3718 // ProfilePublicKey 3719 data = append(data, UintToBuf(uint64(len(txnData.ProfilePublicKey)))...) 3720 data = append(data, txnData.ProfilePublicKey...) 3721 3722 // OperationType byte 3723 data = append(data, byte(txnData.OperationType)) 3724 3725 // DeSoToSellNanos uint64 3726 data = append(data, UintToBuf(uint64(txnData.DeSoToSellNanos))...) 3727 3728 // CreatorCoinToSellNanos uint64 3729 data = append(data, UintToBuf(uint64(txnData.CreatorCoinToSellNanos))...) 3730 // DeSoToAddNanos uint64 3731 data = append(data, UintToBuf(uint64(txnData.DeSoToAddNanos))...) 3732 3733 // MinDeSoExpectedNanos uint64 3734 data = append(data, UintToBuf(uint64(txnData.MinDeSoExpectedNanos))...) 3735 // MinCreatorCoinExpectedNanos uint64 3736 data = append(data, UintToBuf(uint64(txnData.MinCreatorCoinExpectedNanos))...) 3737 3738 return data, nil 3739 } 3740 3741 func (txnData *CreatorCoinMetadataa) FromBytes(dataa []byte) error { 3742 ret := CreatorCoinMetadataa{} 3743 rr := bytes.NewReader(dataa) 3744 3745 // ProfilePublicKey 3746 var err error 3747 ret.ProfilePublicKey, err = ReadVarString(rr) 3748 if err != nil { 3749 return fmt.Errorf( 3750 "CreatorCoinMetadataa.FromBytes: Error reading ProfilePublicKey: %v", err) 3751 } 3752 3753 // OperationType byte 3754 operationType, err := rr.ReadByte() 3755 if err != nil { 3756 return fmt.Errorf( 3757 "CreatorCoinMetadataa.FromBytes: Error reading OperationType: %v", err) 3758 } 3759 ret.OperationType = CreatorCoinOperationType(operationType) 3760 3761 // DeSoToSellNanos uint64 3762 ret.DeSoToSellNanos, err = ReadUvarint(rr) 3763 if err != nil { 3764 return fmt.Errorf("CreatorCoinMetadata.FromBytes: Error reading DeSoToSellNanos: %v", err) 3765 } 3766 3767 // CreatorCoinToSellNanos uint64 3768 ret.CreatorCoinToSellNanos, err = ReadUvarint(rr) 3769 if err != nil { 3770 return fmt.Errorf("CreatorCoinMetadata.FromBytes: Error reading CreatorCoinToSellNanos: %v", err) 3771 } 3772 3773 // DeSoToAddNanos uint64 3774 ret.DeSoToAddNanos, err = ReadUvarint(rr) 3775 if err != nil { 3776 return fmt.Errorf("CreatorCoinMetadata.FromBytes: Error reading DeSoToAddNanos: %v", err) 3777 } 3778 3779 // MinDeSoExpectedNanos uint64 3780 ret.MinDeSoExpectedNanos, err = ReadUvarint(rr) 3781 if err != nil { 3782 return fmt.Errorf("CreatorCoinMetadata.FromBytes: Error reading MinDeSoExpectedNanos: %v", err) 3783 } 3784 3785 // MinCreatorCoinExpectedNanos uint64 3786 ret.MinCreatorCoinExpectedNanos, err = ReadUvarint(rr) 3787 if err != nil { 3788 return fmt.Errorf("CreatorCoinMetadata.FromBytes: Error reading MinCreatorCoinExpectedNanos: %v", err) 3789 } 3790 3791 *txnData = ret 3792 return nil 3793 } 3794 3795 func (txnData *CreatorCoinMetadataa) New() DeSoTxnMetadata { 3796 return &CreatorCoinMetadataa{} 3797 } 3798 3799 // ================================================================== 3800 // CreatorCoinTransferMetadataa 3801 // ================================================================== 3802 3803 type CreatorCoinTransferMetadataa struct { 3804 // ProfilePublicKey is the public key of the profile that owns the 3805 // coin the person wants to transer. Creator coins can only be 3806 // transferred if a valid profile exists. 3807 ProfilePublicKey []byte 3808 3809 CreatorCoinToTransferNanos uint64 3810 ReceiverPublicKey []byte 3811 } 3812 3813 func (txnData *CreatorCoinTransferMetadataa) GetTxnType() TxnType { 3814 return TxnTypeCreatorCoinTransfer 3815 } 3816 3817 func (txnData *CreatorCoinTransferMetadataa) ToBytes(preSignature bool) ([]byte, error) { 3818 data := []byte{} 3819 3820 // ProfilePublicKey 3821 data = append(data, UintToBuf(uint64(len(txnData.ProfilePublicKey)))...) 3822 data = append(data, txnData.ProfilePublicKey...) 3823 3824 // CreatorCoinToTransferNanos uint64 3825 data = append(data, UintToBuf(uint64(txnData.CreatorCoinToTransferNanos))...) 3826 3827 // ReceiverPublicKey 3828 data = append(data, UintToBuf(uint64(len(txnData.ReceiverPublicKey)))...) 3829 data = append(data, txnData.ReceiverPublicKey...) 3830 3831 return data, nil 3832 } 3833 3834 func (txnData *CreatorCoinTransferMetadataa) FromBytes(dataa []byte) error { 3835 ret := CreatorCoinTransferMetadataa{} 3836 rr := bytes.NewReader(dataa) 3837 3838 // ProfilePublicKey 3839 var err error 3840 ret.ProfilePublicKey, err = ReadVarString(rr) 3841 if err != nil { 3842 return fmt.Errorf( 3843 "CreatorCoinTransferMetadataa.FromBytes: Error reading ProfilePublicKey: %v", err) 3844 } 3845 3846 // CreatorCoinToTransferNanos uint64 3847 ret.CreatorCoinToTransferNanos, err = ReadUvarint(rr) 3848 if err != nil { 3849 return fmt.Errorf("CreatorCoinTransferMetadata.FromBytes: Error reading CreatorCoinToSellNanos: %v", err) 3850 } 3851 3852 // ReceiverPublicKey 3853 ret.ReceiverPublicKey, err = ReadVarString(rr) 3854 if err != nil { 3855 return fmt.Errorf( 3856 "CreatorCoinTransferMetadataa.FromBytes: Error reading ReceiverPublicKey: %v", err) 3857 } 3858 3859 *txnData = ret 3860 return nil 3861 } 3862 3863 func (txnData *CreatorCoinTransferMetadataa) New() DeSoTxnMetadata { 3864 return &CreatorCoinTransferMetadataa{} 3865 } 3866 3867 // ================================================================== 3868 // CreateNFTMetadata 3869 // ================================================================== 3870 3871 type CreateNFTMetadata struct { 3872 NFTPostHash *BlockHash 3873 NumCopies uint64 3874 HasUnlockable bool 3875 IsForSale bool 3876 MinBidAmountNanos uint64 3877 NFTRoyaltyToCreatorBasisPoints uint64 3878 NFTRoyaltyToCoinBasisPoints uint64 3879 } 3880 3881 func (txnData *CreateNFTMetadata) GetTxnType() TxnType { 3882 return TxnTypeCreateNFT 3883 } 3884 3885 func (txnData *CreateNFTMetadata) ToBytes(preSignature bool) ([]byte, error) { 3886 // Validate the metadata before encoding it. 3887 // 3888 // Post hash must be included and must have the expected length. 3889 if len(txnData.NFTPostHash) != HashSizeBytes { 3890 return nil, fmt.Errorf("CreateNFTMetadata.ToBytes: NFTPostHash "+ 3891 "has length %d != %d", len(txnData.NFTPostHash), HashSizeBytes) 3892 } 3893 3894 data := []byte{} 3895 3896 // NFTPostHash 3897 data = append(data, txnData.NFTPostHash[:]...) 3898 3899 // NumCopies uint64 3900 data = append(data, UintToBuf(txnData.NumCopies)...) 3901 3902 // HasUnlockable 3903 data = append(data, BoolToByte(txnData.HasUnlockable)) 3904 3905 // IsForSale 3906 data = append(data, BoolToByte(txnData.IsForSale)) 3907 3908 // MinBidAmountNanos uint64 3909 data = append(data, UintToBuf(txnData.MinBidAmountNanos)...) 3910 3911 // NFTRoyaltyToCreatorBasisPoints uint64 3912 data = append(data, UintToBuf(txnData.NFTRoyaltyToCreatorBasisPoints)...) 3913 3914 // NFTRoyaltyToCoinBasisPoints uint64 3915 data = append(data, UintToBuf(txnData.NFTRoyaltyToCoinBasisPoints)...) 3916 3917 return data, nil 3918 } 3919 3920 func (txnData *CreateNFTMetadata) FromBytes(dataa []byte) error { 3921 ret := CreateNFTMetadata{} 3922 rr := bytes.NewReader(dataa) 3923 3924 // NFTPostHash 3925 ret.NFTPostHash = &BlockHash{} 3926 _, err := io.ReadFull(rr, ret.NFTPostHash[:]) 3927 if err != nil { 3928 return fmt.Errorf( 3929 "CreateNFTMetadata.FromBytes: Error reading NFTPostHash: %v", err) 3930 } 3931 3932 // NumCopies uint64 3933 ret.NumCopies, err = ReadUvarint(rr) 3934 if err != nil { 3935 return fmt.Errorf("CreateNFTMetadata.FromBytes: Error reading NumCopies: %v", err) 3936 } 3937 3938 // HasUnlockable 3939 ret.HasUnlockable = ReadBoolByte(rr) 3940 3941 // IsForSale 3942 ret.IsForSale = ReadBoolByte(rr) 3943 3944 // MinBidAmountNanos uint64 3945 ret.MinBidAmountNanos, err = ReadUvarint(rr) 3946 if err != nil { 3947 return fmt.Errorf("CreateNFTMetadata.FromBytes: Error reading MinBidAmountNanos: %v", err) 3948 } 3949 3950 // NFTRoyaltyToCreatorBasisPoints uint64 3951 ret.NFTRoyaltyToCreatorBasisPoints, err = ReadUvarint(rr) 3952 if err != nil { 3953 return fmt.Errorf("CreateNFTMetadata.FromBytes: Error reading NFTRoyaltyToCreatorBasisPoints: %v", err) 3954 } 3955 3956 // NFTRoyaltyToCoinBasisPoints uint64 3957 ret.NFTRoyaltyToCoinBasisPoints, err = ReadUvarint(rr) 3958 if err != nil { 3959 return fmt.Errorf("CreateNFTMetadata.FromBytes: Error reading NFTRoyaltyToCoinBasisPoints: %v", err) 3960 } 3961 3962 *txnData = ret 3963 return nil 3964 } 3965 3966 func (txnData *CreateNFTMetadata) New() DeSoTxnMetadata { 3967 return &CreateNFTMetadata{} 3968 } 3969 3970 // ================================================================== 3971 // UpdateNFTMetadata 3972 // ================================================================== 3973 3974 type UpdateNFTMetadata struct { 3975 NFTPostHash *BlockHash 3976 SerialNumber uint64 3977 IsForSale bool 3978 MinBidAmountNanos uint64 3979 } 3980 3981 func (txnData *UpdateNFTMetadata) GetTxnType() TxnType { 3982 return TxnTypeUpdateNFT 3983 } 3984 3985 func (txnData *UpdateNFTMetadata) ToBytes(preSignature bool) ([]byte, error) { 3986 // Validate the metadata before encoding it. 3987 // 3988 // Post hash must be included and must have the expected length. 3989 if len(txnData.NFTPostHash) != HashSizeBytes { 3990 return nil, fmt.Errorf("UpdateNFTMetadata.ToBytes: NFTPostHash "+ 3991 "has length %d != %d", len(txnData.NFTPostHash), HashSizeBytes) 3992 } 3993 3994 data := []byte{} 3995 3996 // NFTPostHash 3997 data = append(data, txnData.NFTPostHash[:]...) 3998 3999 // SerialNumber uint64 4000 data = append(data, UintToBuf(txnData.SerialNumber)...) 4001 4002 // IsForSale 4003 data = append(data, BoolToByte(txnData.IsForSale)) 4004 4005 // MinBidAmountNanos uint64 4006 data = append(data, UintToBuf(txnData.MinBidAmountNanos)...) 4007 4008 return data, nil 4009 } 4010 4011 func (txnData *UpdateNFTMetadata) FromBytes(dataa []byte) error { 4012 ret := UpdateNFTMetadata{} 4013 rr := bytes.NewReader(dataa) 4014 4015 // NFTPostHash 4016 ret.NFTPostHash = &BlockHash{} 4017 _, err := io.ReadFull(rr, ret.NFTPostHash[:]) 4018 if err != nil { 4019 return fmt.Errorf( 4020 "UpdateNFTMetadata.FromBytes: Error reading NFTPostHash: %v", err) 4021 } 4022 4023 // SerialNumber uint64 4024 ret.SerialNumber, err = ReadUvarint(rr) 4025 if err != nil { 4026 return fmt.Errorf("UpdateNFTMetadata.FromBytes: Error reading SerialNumber: %v", err) 4027 } 4028 4029 // IsForSale 4030 ret.IsForSale = ReadBoolByte(rr) 4031 4032 // SerialNumber uint64 4033 ret.MinBidAmountNanos, err = ReadUvarint(rr) 4034 if err != nil { 4035 return fmt.Errorf("UpdateNFTMetadata.FromBytes: Error reading MinBidAmountNanos: %v", err) 4036 } 4037 4038 *txnData = ret 4039 return nil 4040 } 4041 4042 func (txnData *UpdateNFTMetadata) New() DeSoTxnMetadata { 4043 return &UpdateNFTMetadata{} 4044 } 4045 4046 // ================================================================== 4047 // AcceptNFTBidMetadata 4048 // ================================================================== 4049 4050 type AcceptNFTBidMetadata struct { 4051 NFTPostHash *BlockHash 4052 SerialNumber uint64 4053 BidderPKID *PKID 4054 BidAmountNanos uint64 4055 UnlockableText []byte 4056 4057 // When an NFT owner accepts a bid, they must specify the bidder's UTXO inputs they will lock up 4058 // as payment for the purchase. This prevents the transaction from accidentally using UTXOs 4059 // that are used by future transactions. 4060 BidderInputs []*DeSoInput 4061 } 4062 4063 func (txnData *AcceptNFTBidMetadata) GetTxnType() TxnType { 4064 return TxnTypeAcceptNFTBid 4065 } 4066 4067 func (txnData *AcceptNFTBidMetadata) ToBytes(preSignature bool) ([]byte, error) { 4068 // Validate the metadata before encoding it. 4069 // 4070 // Post hash and pub key must be included and must have the expected length. 4071 if len(txnData.NFTPostHash) != HashSizeBytes { 4072 return nil, fmt.Errorf("AcceptNFTBidMetadata.ToBytes: NFTPostHash "+ 4073 "has length %d != %d", len(txnData.NFTPostHash), HashSizeBytes) 4074 } 4075 if len(txnData.BidderPKID) != btcec.PubKeyBytesLenCompressed { 4076 return nil, fmt.Errorf("AcceptNFTBidMetadata.ToBytes: BidderPublicKey "+ 4077 "has length %d != %d", len(txnData.BidderPKID), btcec.PubKeyBytesLenCompressed) 4078 } 4079 4080 data := []byte{} 4081 4082 // NFTPostHash 4083 data = append(data, txnData.NFTPostHash[:]...) 4084 4085 // SerialNumber uint64 4086 data = append(data, UintToBuf(txnData.SerialNumber)...) 4087 4088 // BidderPKID 4089 data = append(data, UintToBuf(uint64(len(txnData.BidderPKID)))...) 4090 data = append(data, txnData.BidderPKID[:]...) 4091 4092 // BidAmountNanos uint64 4093 data = append(data, UintToBuf(txnData.BidAmountNanos)...) 4094 4095 // UnlockableText 4096 data = append(data, UintToBuf(uint64(len(txnData.UnlockableText)))...) 4097 data = append(data, txnData.UnlockableText...) 4098 4099 // Serialize the bidder inputs 4100 data = append(data, UintToBuf(uint64(len(txnData.BidderInputs)))...) 4101 for _, desoInput := range txnData.BidderInputs { 4102 data = append(data, desoInput.TxID[:]...) 4103 data = append(data, UintToBuf(uint64(desoInput.Index))...) 4104 } 4105 4106 return data, nil 4107 } 4108 4109 func (txnData *AcceptNFTBidMetadata) FromBytes(dataa []byte) error { 4110 ret := AcceptNFTBidMetadata{} 4111 rr := bytes.NewReader(dataa) 4112 4113 // NFTPostHash 4114 ret.NFTPostHash = &BlockHash{} 4115 _, err := io.ReadFull(rr, ret.NFTPostHash[:]) 4116 if err != nil { 4117 return fmt.Errorf( 4118 "AcceptNFTBidMetadata.FromBytes: Error reading NFTPostHash: %v", err) 4119 } 4120 4121 // SerialNumber uint64 4122 ret.SerialNumber, err = ReadUvarint(rr) 4123 if err != nil { 4124 return fmt.Errorf("AcceptNFTBidMetadata.FromBytes: Error reading SerialNumber: %v", err) 4125 } 4126 4127 // BidderPKID 4128 bidderPKIDBytes, err := ReadVarString(rr) 4129 if err != nil { 4130 return fmt.Errorf( 4131 "AcceptNFTBidMetadata.FromBytes: Error reading BidderPublicKey: %v", err) 4132 } 4133 ret.BidderPKID = PublicKeyToPKID(bidderPKIDBytes) 4134 4135 // BidAmountNanos uint64 4136 ret.BidAmountNanos, err = ReadUvarint(rr) 4137 if err != nil { 4138 return fmt.Errorf("AcceptNFTBidMetadata.FromBytes: Error reading BidAmountNanos: %v", err) 4139 } 4140 4141 // UnlockableText 4142 unlockableTextLen, err := ReadUvarint(rr) 4143 if err != nil { 4144 return errors.Wrapf(err, "AcceptNFTBidMetadata.FromBytes: Problem "+ 4145 "decoding UnlockableText length") 4146 } 4147 if unlockableTextLen > MaxMessagePayload { 4148 return fmt.Errorf("AcceptNFTBidMetadata.FromBytes: unlockableTextLen %d "+ 4149 "exceeds max %d", unlockableTextLen, MaxMessagePayload) 4150 } 4151 ret.UnlockableText = make([]byte, unlockableTextLen) 4152 _, err = io.ReadFull(rr, ret.UnlockableText) 4153 if err != nil { 4154 return fmt.Errorf("AcceptNFTBidMetadata.FromBytes: Error reading EncryptedText: %v", err) 4155 } 4156 4157 // De-serialize the inputs 4158 numInputs, err := ReadUvarint(rr) 4159 if err != nil { 4160 return errors.Wrapf(err, "AcceptNFTBidMetadata.FromBytes: Problem getting length of inputs") 4161 } 4162 for ii := uint64(0); ii < numInputs; ii++ { 4163 currentInput := NewDeSoInput() 4164 _, err = io.ReadFull(rr, currentInput.TxID[:]) 4165 if err != nil { 4166 return errors.Wrapf(err, "AcceptNFTBidMetadata.FromBytes: Problem converting input txid") 4167 } 4168 inputIndex, err := ReadUvarint(rr) 4169 if err != nil { 4170 return errors.Wrapf(err, "AcceptNFTBidMetadata.FromBytes: Problem converting input index") 4171 } 4172 if inputIndex > uint64(^uint32(0)) { 4173 return fmt.Errorf("AcceptNFTBidMetadata.FromBytes: Input index (%d) must not exceed (%d)", inputIndex, ^uint32(0)) 4174 } 4175 currentInput.Index = uint32(inputIndex) 4176 4177 ret.BidderInputs = append(ret.BidderInputs, currentInput) 4178 } 4179 4180 *txnData = ret 4181 return nil 4182 } 4183 4184 func (txnData *AcceptNFTBidMetadata) New() DeSoTxnMetadata { 4185 return &AcceptNFTBidMetadata{} 4186 } 4187 4188 // ================================================================== 4189 // NFTBidMetadata 4190 // ================================================================== 4191 4192 type NFTBidMetadata struct { 4193 NFTPostHash *BlockHash 4194 SerialNumber uint64 4195 BidAmountNanos uint64 4196 } 4197 4198 func (txnData *NFTBidMetadata) GetTxnType() TxnType { 4199 return TxnTypeNFTBid 4200 } 4201 4202 func (txnData *NFTBidMetadata) ToBytes(preSignature bool) ([]byte, error) { 4203 // Validate the metadata before encoding it. 4204 // 4205 // Post hash must be included and must have the expected length. 4206 if len(txnData.NFTPostHash) != HashSizeBytes { 4207 return nil, fmt.Errorf("NFTBidMetadata.ToBytes: NFTPostHash "+ 4208 "has length %d != %d", len(txnData.NFTPostHash), HashSizeBytes) 4209 } 4210 4211 data := []byte{} 4212 4213 // NFTPostHash 4214 data = append(data, txnData.NFTPostHash[:]...) 4215 4216 // SerialNumber uint64 4217 data = append(data, UintToBuf(txnData.SerialNumber)...) 4218 4219 // BidAmountNanos uint64 4220 data = append(data, UintToBuf(txnData.BidAmountNanos)...) 4221 4222 return data, nil 4223 } 4224 4225 func (txnData *NFTBidMetadata) FromBytes(dataa []byte) error { 4226 ret := NFTBidMetadata{} 4227 rr := bytes.NewReader(dataa) 4228 4229 // NFTPostHash 4230 ret.NFTPostHash = &BlockHash{} 4231 _, err := io.ReadFull(rr, ret.NFTPostHash[:]) 4232 if err != nil { 4233 return fmt.Errorf( 4234 "NFTBidMetadata.FromBytes: Error reading NFTPostHash: %v", err) 4235 } 4236 4237 // SerialNumber uint64 4238 ret.SerialNumber, err = ReadUvarint(rr) 4239 if err != nil { 4240 return fmt.Errorf("NFTBidMetadata.FromBytes: Error reading SerialNumber: %v", err) 4241 } 4242 4243 // BidAmountNanos uint64 4244 ret.BidAmountNanos, err = ReadUvarint(rr) 4245 if err != nil { 4246 return fmt.Errorf("NFTBidMetadata.FromBytes: Error reading BidAmountNanos: %v", err) 4247 } 4248 4249 *txnData = ret 4250 return nil 4251 } 4252 4253 func (txnData *NFTBidMetadata) New() DeSoTxnMetadata { 4254 return &NFTBidMetadata{} 4255 } 4256 4257 // ================================================================== 4258 // NFTTransferMetadata 4259 // ================================================================== 4260 4261 type NFTTransferMetadata struct { 4262 NFTPostHash *BlockHash 4263 SerialNumber uint64 4264 ReceiverPublicKey []byte 4265 UnlockableText []byte 4266 } 4267 4268 func (txnData *NFTTransferMetadata) GetTxnType() TxnType { 4269 return TxnTypeNFTTransfer 4270 } 4271 4272 func (txnData *NFTTransferMetadata) ToBytes(preSignature bool) ([]byte, error) { 4273 // Validate the metadata before encoding it. 4274 // 4275 // Post hash must be included and must have the expected length. 4276 if len(txnData.NFTPostHash) != HashSizeBytes { 4277 return nil, fmt.Errorf("NFTTransferMetadata.ToBytes: NFTPostHash "+ 4278 "has length %d != %d", len(txnData.NFTPostHash), HashSizeBytes) 4279 } 4280 4281 data := []byte{} 4282 4283 // NFTPostHash 4284 data = append(data, txnData.NFTPostHash[:]...) 4285 4286 // SerialNumber uint64 4287 data = append(data, UintToBuf(txnData.SerialNumber)...) 4288 4289 // ReceiverPublicKey 4290 data = append(data, UintToBuf(uint64(len(txnData.ReceiverPublicKey)))...) 4291 data = append(data, txnData.ReceiverPublicKey...) 4292 4293 // UnlockableText 4294 data = append(data, UintToBuf(uint64(len(txnData.UnlockableText)))...) 4295 data = append(data, txnData.UnlockableText...) 4296 4297 return data, nil 4298 } 4299 4300 func (txnData *NFTTransferMetadata) FromBytes(dataa []byte) error { 4301 ret := NFTTransferMetadata{} 4302 rr := bytes.NewReader(dataa) 4303 4304 // NFTPostHash 4305 ret.NFTPostHash = &BlockHash{} 4306 _, err := io.ReadFull(rr, ret.NFTPostHash[:]) 4307 if err != nil { 4308 return fmt.Errorf( 4309 "NFTTransferMetadata.FromBytes: Error reading NFTPostHash: %v", err) 4310 } 4311 4312 // SerialNumber uint64 4313 ret.SerialNumber, err = ReadUvarint(rr) 4314 if err != nil { 4315 return fmt.Errorf("NFTTransferMetadata.FromBytes: Error reading SerialNumber: %v", err) 4316 } 4317 4318 // ReceiverPublicKey 4319 ret.ReceiverPublicKey, err = ReadVarString(rr) 4320 if err != nil { 4321 return fmt.Errorf( 4322 "NFTTransferMetadataa.FromBytes: Error reading ReceiverPublicKey: %v", err) 4323 } 4324 4325 // UnlockableText 4326 unlockableTextLen, err := ReadUvarint(rr) 4327 if err != nil { 4328 return errors.Wrapf(err, "NFTTransferMetadata.FromBytes: Problem "+ 4329 "decoding UnlockableText length") 4330 } 4331 if unlockableTextLen > MaxMessagePayload { 4332 return fmt.Errorf("NFTTransferMetadata.FromBytes: unlockableTextLen %d "+ 4333 "exceeds max %d", unlockableTextLen, MaxMessagePayload) 4334 } 4335 ret.UnlockableText = make([]byte, unlockableTextLen) 4336 _, err = io.ReadFull(rr, ret.UnlockableText) 4337 if err != nil { 4338 return fmt.Errorf("NFTTransferMetadata.FromBytes: Error reading EncryptedText: %v", err) 4339 } 4340 4341 *txnData = ret 4342 return nil 4343 } 4344 4345 func (txnData *NFTTransferMetadata) New() DeSoTxnMetadata { 4346 return &NFTTransferMetadata{} 4347 } 4348 4349 // ================================================================== 4350 // AcceptNFTTransferMetadata 4351 // ================================================================== 4352 4353 type AcceptNFTTransferMetadata struct { 4354 NFTPostHash *BlockHash 4355 SerialNumber uint64 4356 } 4357 4358 func (txnData *AcceptNFTTransferMetadata) GetTxnType() TxnType { 4359 return TxnTypeAcceptNFTTransfer 4360 } 4361 4362 func (txnData *AcceptNFTTransferMetadata) ToBytes(preSignature bool) ([]byte, error) { 4363 // Validate the metadata before encoding it. 4364 // 4365 // Post hash must be included and must have the expected length. 4366 if len(txnData.NFTPostHash) != HashSizeBytes { 4367 return nil, fmt.Errorf("AcceptNFTTransferMetadata.ToBytes: NFTPostHash "+ 4368 "has length %d != %d", len(txnData.NFTPostHash), HashSizeBytes) 4369 } 4370 4371 data := []byte{} 4372 4373 // NFTPostHash 4374 data = append(data, txnData.NFTPostHash[:]...) 4375 4376 // SerialNumber uint64 4377 data = append(data, UintToBuf(txnData.SerialNumber)...) 4378 4379 return data, nil 4380 } 4381 4382 func (txnData *AcceptNFTTransferMetadata) FromBytes(dataa []byte) error { 4383 ret := AcceptNFTTransferMetadata{} 4384 rr := bytes.NewReader(dataa) 4385 4386 // NFTPostHash 4387 ret.NFTPostHash = &BlockHash{} 4388 _, err := io.ReadFull(rr, ret.NFTPostHash[:]) 4389 if err != nil { 4390 return fmt.Errorf( 4391 "AcceptNFTTransferMetadata.FromBytes: Error reading NFTPostHash: %v", err) 4392 } 4393 4394 // SerialNumber uint64 4395 ret.SerialNumber, err = ReadUvarint(rr) 4396 if err != nil { 4397 return fmt.Errorf("AcceptNFTTransferMetadata.FromBytes: Error reading SerialNumber: %v", err) 4398 } 4399 4400 *txnData = ret 4401 return nil 4402 } 4403 4404 func (txnData *AcceptNFTTransferMetadata) New() DeSoTxnMetadata { 4405 return &AcceptNFTTransferMetadata{} 4406 } 4407 4408 // ================================================================== 4409 // BurnNFTMetadata 4410 // ================================================================== 4411 4412 type BurnNFTMetadata struct { 4413 NFTPostHash *BlockHash 4414 SerialNumber uint64 4415 } 4416 4417 func (txnData *BurnNFTMetadata) GetTxnType() TxnType { 4418 return TxnTypeBurnNFT 4419 } 4420 4421 func (txnData *BurnNFTMetadata) ToBytes(preSignature bool) ([]byte, error) { 4422 // Validate the metadata before encoding it. 4423 // 4424 // Post hash must be included and must have the expected length. 4425 if len(txnData.NFTPostHash) != HashSizeBytes { 4426 return nil, fmt.Errorf("BurnNFTMetadata.ToBytes: NFTPostHash "+ 4427 "has length %d != %d", len(txnData.NFTPostHash), HashSizeBytes) 4428 } 4429 4430 data := []byte{} 4431 4432 // NFTPostHash 4433 data = append(data, txnData.NFTPostHash[:]...) 4434 4435 // SerialNumber uint64 4436 data = append(data, UintToBuf(txnData.SerialNumber)...) 4437 4438 return data, nil 4439 } 4440 4441 func (txnData *BurnNFTMetadata) FromBytes(dataa []byte) error { 4442 ret := BurnNFTMetadata{} 4443 rr := bytes.NewReader(dataa) 4444 4445 // NFTPostHash 4446 ret.NFTPostHash = &BlockHash{} 4447 _, err := io.ReadFull(rr, ret.NFTPostHash[:]) 4448 if err != nil { 4449 return fmt.Errorf( 4450 "BurnNFTMetadata.FromBytes: Error reading NFTPostHash: %v", err) 4451 } 4452 4453 // SerialNumber uint64 4454 ret.SerialNumber, err = ReadUvarint(rr) 4455 if err != nil { 4456 return fmt.Errorf("BurnNFTMetadata.FromBytes: Error reading SerialNumber: %v", err) 4457 } 4458 4459 *txnData = ret 4460 return nil 4461 } 4462 4463 func (txnData *BurnNFTMetadata) New() DeSoTxnMetadata { 4464 return &BurnNFTMetadata{} 4465 } 4466 4467 // ================================================================== 4468 // SwapIdentityMetadataa 4469 // ================================================================== 4470 4471 type SwapIdentityOperationType uint8 4472 4473 type SwapIdentityMetadataa struct { 4474 // TODO: This is currently only accessible by ParamUpdater. This avoids the 4475 // possibility that a user will stomp over another user's profile, and 4476 // simplifies the logic. In the long run, though, we should eliminate all 4477 // dependencies on ParamUpdater. 4478 4479 // The public key that we are swapping *from*. Doesn't matter which public 4480 // key is *from* and which public key is *to* because it's just a swap. 4481 FromPublicKey []byte 4482 4483 // The public key that we are swapping *to*. Doesn't matter which public 4484 // key is *from* and which public key is *to* because it's just a swap. 4485 ToPublicKey []byte 4486 } 4487 4488 func (txnData *SwapIdentityMetadataa) GetTxnType() TxnType { 4489 return TxnTypeSwapIdentity 4490 } 4491 4492 func (txnData *SwapIdentityMetadataa) ToBytes(preSignature bool) ([]byte, error) { 4493 data := []byte{} 4494 4495 // FromPublicKey 4496 data = append(data, UintToBuf(uint64(len(txnData.FromPublicKey)))...) 4497 data = append(data, txnData.FromPublicKey...) 4498 4499 // ToPublicKey 4500 data = append(data, UintToBuf(uint64(len(txnData.ToPublicKey)))...) 4501 data = append(data, txnData.ToPublicKey...) 4502 4503 return data, nil 4504 } 4505 4506 func (txnData *SwapIdentityMetadataa) FromBytes(dataa []byte) error { 4507 ret := SwapIdentityMetadataa{} 4508 rr := bytes.NewReader(dataa) 4509 4510 // FromPublicKey 4511 var err error 4512 ret.FromPublicKey, err = ReadVarString(rr) 4513 if err != nil { 4514 return fmt.Errorf( 4515 "SwapIdentityMetadataa.FromBytes: Error reading FromPublicKey: %v", err) 4516 } 4517 4518 // ToPublicKey 4519 ret.ToPublicKey, err = ReadVarString(rr) 4520 if err != nil { 4521 return fmt.Errorf( 4522 "SwapIdentityMetadataa.FromBytes: Error reading ToPublicKey: %v", err) 4523 } 4524 4525 *txnData = ret 4526 return nil 4527 } 4528 4529 func (txnData *SwapIdentityMetadataa) New() DeSoTxnMetadata { 4530 return &SwapIdentityMetadataa{} 4531 } 4532 4533 // ================================================================== 4534 // AuthorizeDerivedKeyMetadata 4535 // ================================================================== 4536 4537 type AuthorizeDerivedKeyOperationType uint8 4538 4539 const ( 4540 AuthorizeDerivedKeyOperationNotValid AuthorizeDerivedKeyOperationType = 0 4541 AuthorizeDerivedKeyOperationValid AuthorizeDerivedKeyOperationType = 1 4542 ) 4543 4544 type AuthorizeDerivedKeyMetadata struct { 4545 // DerivedPublicKey is the key that is authorized to sign transactions 4546 // on behalf of the public key owner. 4547 DerivedPublicKey []byte 4548 4549 // ExpirationBlock is the block at which this authorization becomes invalid. 4550 ExpirationBlock uint64 4551 4552 // OperationType determines if transaction validates or invalidates derived key. 4553 OperationType AuthorizeDerivedKeyOperationType 4554 4555 // AccessSignature is the signed hash of (derivedPublicKey + expirationBlock) 4556 // made with the ownerPublicKey. Signature is in the DER format. 4557 AccessSignature []byte 4558 } 4559 4560 func (txnData *AuthorizeDerivedKeyMetadata) GetTxnType() TxnType { 4561 return TxnTypeAuthorizeDerivedKey 4562 } 4563 4564 func (txnData *AuthorizeDerivedKeyMetadata) ToBytes(preSignature bool) ([]byte, error) { 4565 data := []byte{} 4566 4567 // DerivedPublicKey 4568 data = append(data, UintToBuf(uint64(len(txnData.DerivedPublicKey)))...) 4569 data = append(data, txnData.DerivedPublicKey...) 4570 4571 // ExpirationBlock uint64 4572 data = append(data, UintToBuf(uint64(txnData.ExpirationBlock))...) 4573 4574 // OperationType byte 4575 data = append(data, byte(txnData.OperationType)) 4576 4577 // AccessSignature 4578 data = append(data, UintToBuf(uint64(len(txnData.AccessSignature)))...) 4579 data = append(data, txnData.AccessSignature...) 4580 4581 return data, nil 4582 } 4583 4584 func (txnData *AuthorizeDerivedKeyMetadata) FromBytes(data []byte) error { 4585 ret := AuthorizeDerivedKeyMetadata{} 4586 rr := bytes.NewReader(data) 4587 4588 // DerivedPublicKey 4589 var err error 4590 ret.DerivedPublicKey, err = ReadVarString(rr) 4591 if err != nil { 4592 return fmt.Errorf( 4593 "AuthorizeDerivedKeyMetadata.FromBytes: Error reading DerivedPublicKey: %v", err) 4594 } 4595 4596 // ExpirationBlock uint64 4597 ret.ExpirationBlock, err = ReadUvarint(rr) 4598 if err != nil { 4599 return fmt.Errorf( 4600 "AuthorizeDerivedKeyMetadata.FromBytes: Error reading ExpirationBlock: %v", err) 4601 } 4602 4603 // OperationType byte 4604 operationType, err := rr.ReadByte() 4605 if err != nil { 4606 return fmt.Errorf( 4607 "AuthorizeDerivedKeyMetadata.FromBytes: Error reading OperationType: %v", err) 4608 } 4609 ret.OperationType = AuthorizeDerivedKeyOperationType(operationType) 4610 4611 // AccessSignature 4612 ret.AccessSignature, err = ReadVarString(rr) 4613 if err != nil { 4614 return fmt.Errorf( 4615 "AuthorizeDerivedKeyMetadata.FromBytes: Error reading AccessSignature: %v", err) 4616 } 4617 4618 *txnData = ret 4619 return nil 4620 } 4621 4622 func (txnData *AuthorizeDerivedKeyMetadata) New() DeSoTxnMetadata { 4623 return &AuthorizeDerivedKeyMetadata{} 4624 }