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.

149 lines
4.7 KiB

  1. // Copyright 2017-2018 DERO Project. All rights reserved.
  2. // Use of this source code in any form is governed by RESEARCH license.
  3. // license can be found in the LICENSE file.
  4. // GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8
  5. //
  6. //
  7. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
  8. // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  9. // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  10. // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  11. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  12. // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  13. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  14. // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  15. // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16. package p2p
  17. import "bytes"
  18. import "github.com/romana/rlog"
  19. import log "github.com/sirupsen/logrus"
  20. import "github.com/deroproject/derosuite/block"
  21. //import "github.com/deroproject/derosuite/blockchain"
  22. import "github.com/deroproject/derosuite/transaction"
  23. // if the incoming blob contains block with included transactions
  24. //00009F94 01 11 01 01 01 01 02 01 01 08 06 62 6c 6f 63 6b ........ ...block
  25. //00009FA4 73 8c 04 08 05 62 6c 6f 63 6b 0a fd 03 06 06 cd s....blo ck......
  26. // if the incoming blob contains block without any tx
  27. //00009EB4 01 11 01 01 01 01 02 01 01 08 06 62 6c 6f 63 6b ........ ...block
  28. //00009EC4 73 8c 08 04 05 62 6c 6f 63 6b 0a e5 01 01 00 00 s....blo ck......
  29. // if the incoming blob only contains a TX
  30. // FIXME this code can also be shared by NOTIFY_NEW_BLOCK, NOTIFY_NEW_TRANSACTIONS
  31. // we trigger this if we want to request any TX or block from the peer
  32. func Handle_BC_Notify_Response_GetObjects(connection *Connection,
  33. i_command_header *Levin_Header, buf []byte) {
  34. var bl block.Block
  35. var complete_bl block.Complete_Block
  36. complete_block := false
  37. // deserialize data header
  38. var i_data_header Levin_Data_Header // incoming data header
  39. err := i_data_header.DeSerialize(buf)
  40. if err != nil {
  41. log.Debugf("We should destroy connection here, data header cnot deserialized")
  42. return
  43. }
  44. // check whether the response contains block
  45. pos := bytes.Index(i_data_header.Data, []byte("blocks")) // at this point to
  46. buf = i_data_header.Data
  47. if pos > 0 { // the data contains atleast 1 block
  48. pos += 6
  49. buf = i_data_header.Data[pos:]
  50. pos := bytes.Index(buf, []byte("block"))
  51. // find inner position of block
  52. pos = pos + 6 // jump to varint length position and decode
  53. buf = buf[pos:]
  54. block_length, done := Decode_Boost_Varint(buf)
  55. rlog.Tracef(9, "Block length %d %x\n", block_length, buf[:8])
  56. buf = buf[done:]
  57. block_buf := buf[:block_length]
  58. err = bl.Deserialize(block_buf)
  59. if err != nil {
  60. log.Debugf("Block could not be deserialized successfully err %s\n", err)
  61. log.Debugf("We should destroy connection here, block not deserialized")
  62. return
  63. }
  64. hash := bl.GetHash()
  65. rlog.Tracef(9, "Block deserialized successfully %x\n", hash[:32])
  66. rlog.Tracef(9, "Tx hash length %d\n", len(bl.Tx_hashes))
  67. for i := range bl.Tx_hashes {
  68. rlog.Tracef(9, "%d tx %x\n", i, bl.Tx_hashes[i][:32])
  69. }
  70. // point buffer to check whether any more tx exist
  71. buf = buf[block_length:]
  72. complete_block = true
  73. }
  74. pos = bytes.Index(buf, []byte("\x03txs\x8a")) // at this point to
  75. if pos > -1 {
  76. rlog.Tracef(9, "txt pos %d\n", pos)
  77. buf = buf[pos+5:]
  78. // decode remain data length ( though we know it from buffer size, but still verify it )
  79. tx_count, done := Decode_Boost_Varint(buf)
  80. buf = buf[done:]
  81. for i := uint64(0); i < tx_count; i++ {
  82. var tx transaction.Transaction
  83. tx_len, done := Decode_Boost_Varint(buf)
  84. buf = buf[done:]
  85. rlog.Tracef(9, "tx count %d i %d tx_len %d\n", tx_count, i, tx_len)
  86. tx_bytes := buf[:tx_len]
  87. // deserialize and verrify transaction
  88. err = tx.DeserializeHeader(tx_bytes)
  89. if err != nil {
  90. log.Debugf("Transaction could not be deserialized\n")
  91. } else {
  92. hash := tx.GetHash()
  93. rlog.Tracef(9, "Transaction deserialised successfully hash %x\n", hash[:32])
  94. // add tx to block chain, we must verify that the tx has been mined
  95. complete_bl.Txs = append(complete_bl.Txs, &tx)
  96. //chain.Add_TX(&tx)
  97. }
  98. buf = buf[tx_len:] // setup for next tx
  99. }
  100. }
  101. // at this point, if it's a block we should try to add it to block chain
  102. if complete_block {
  103. // add block to chain
  104. log.Debugf("Found a block we should add it to our chain\n")
  105. //chain.Chain_Add(&bl)
  106. complete_bl.Bl = &bl
  107. chain.Add_Complete_Block(&complete_bl) // dispatch the event to block chain
  108. }
  109. }