You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
3.5 KiB

  1. package p2p
  2. import "bytes"
  3. import "github.com/romana/rlog"
  4. import log "github.com/sirupsen/logrus"
  5. import "github.com/deroproject/derosuite/blockchain"
  6. // if the incoming blob contains block with included transactions
  7. //00009F94 01 11 01 01 01 01 02 01 01 08 06 62 6c 6f 63 6b ........ ...block
  8. //00009FA4 73 8c 04 08 05 62 6c 6f 63 6b 0a fd 03 06 06 cd s....blo ck......
  9. // if the incoming blob contains block without any tx
  10. //00009EB4 01 11 01 01 01 01 02 01 01 08 06 62 6c 6f 63 6b ........ ...block
  11. //00009EC4 73 8c 08 04 05 62 6c 6f 63 6b 0a e5 01 01 00 00 s....blo ck......
  12. // if the incoming blob only contains a TX
  13. // FIXME this code can also be shared by NOTIFY_NEW_BLOCK, NOTIFY_NEW_TRANSACTIONS
  14. // we trigger this if we want to request any TX or block from the peer
  15. func Handle_BC_Notify_Response_GetObjects(connection *Connection,
  16. i_command_header *Levin_Header, buf []byte) {
  17. var bl blockchain.Block
  18. complete_block := false
  19. // deserialize data header
  20. var i_data_header Levin_Data_Header // incoming data header
  21. err := i_data_header.DeSerialize(buf)
  22. if err != nil {
  23. log.Debugf("We should destroy connection here, data header cnot deserialized")
  24. return
  25. }
  26. // check whether the response contains block
  27. pos := bytes.Index(i_data_header.Data, []byte("blocks")) // at this point to
  28. buf = i_data_header.Data
  29. if pos > 0 { // the data contains atleast 1 block
  30. pos += 6
  31. buf = i_data_header.Data[pos:]
  32. pos := bytes.Index(buf, []byte("block"))
  33. // find inner position of block
  34. pos = pos + 6 // jump to varint length position and decode
  35. buf = buf[pos:]
  36. block_length, done := Decode_Boost_Varint(buf)
  37. rlog.Tracef(9, "Block length %d %x\n", block_length, buf[:8])
  38. buf = buf[done:]
  39. block_buf := buf[:block_length]
  40. err = bl.Deserialize(block_buf)
  41. if err != nil {
  42. log.Debugf("Block could not be deserialized successfully err %s\n", err)
  43. log.Debugf("We should destroy connection here, block not deserialized")
  44. return
  45. }
  46. hash := bl.GetHash()
  47. rlog.Tracef(9, "Block deserialized successfully %x\n", hash[:32])
  48. rlog.Tracef(9, "Tx hash length %d\n", len(bl.Tx_hashes))
  49. for i := range bl.Tx_hashes {
  50. rlog.Tracef(9, "%d tx %x\n", i, bl.Tx_hashes[i][:32])
  51. }
  52. // point buffer to check whether any more tx exist
  53. buf = buf[block_length:]
  54. complete_block = true
  55. }
  56. pos = bytes.Index(buf, []byte("\x03txs\x8a")) // at this point to
  57. if pos > -1 {
  58. rlog.Tracef(9, "txt pos %d\n", pos)
  59. buf = buf[pos+5:]
  60. // decode remain data length ( though we know it from buffer size, but still verify it )
  61. tx_count, done := Decode_Boost_Varint(buf)
  62. buf = buf[done:]
  63. for i := uint64(0); i < tx_count; i++ {
  64. var tx blockchain.Transaction
  65. tx_len, done := Decode_Boost_Varint(buf)
  66. buf = buf[done:]
  67. rlog.Tracef(9, "tx count %d i %d tx_len %d\n", tx_count, i, tx_len)
  68. tx_bytes := buf[:tx_len]
  69. // deserialize and verrify transaction
  70. err = tx.DeserializeHeader(tx_bytes)
  71. if err != nil {
  72. log.Debugf("Transaction could not be deserialized\n")
  73. } else {
  74. hash := tx.GetHash()
  75. rlog.Tracef(9, "Transaction deserialised successfully hash %x\n", hash[:32])
  76. // add tx to block chain, we must verify that the tx has been mined
  77. chain.Add_TX(&tx)
  78. }
  79. buf = buf[tx_len:] // setup for next tx
  80. }
  81. }
  82. // at this point, if it's a block we should try to add it to block chain
  83. if complete_block {
  84. // add block to chain
  85. log.Debugf("Found a block we should add it to our chain\n")
  86. chain.Chain_Add(&bl)
  87. }
  88. // add all transaction to chains
  89. }