| 106 | } |
| 107 | |
| 108 | func ReadMessage(reader io.Reader) (Message, uint32, error) { |
| 109 | hdr, err := readMessageHeader(reader) |
| 110 | if err != nil { |
| 111 | return nil, 0, err |
| 112 | } |
| 113 | |
| 114 | magic := config.DefConfig.P2PNode.NetworkMagic |
| 115 | if hdr.Magic != magic { |
| 116 | return nil, 0, fmt.Errorf("unmatched magic number %d, expected %d", hdr.Magic, magic) |
| 117 | } |
| 118 | |
| 119 | if hdr.Length > common.MAX_PAYLOAD_LEN { |
| 120 | return nil, 0, fmt.Errorf("msg payload length:%d exceed max payload size: %d", |
| 121 | hdr.Length, common.MAX_PAYLOAD_LEN) |
| 122 | } |
| 123 | |
| 124 | buf := make([]byte, hdr.Length) |
| 125 | _, err = io.ReadFull(reader, buf) |
| 126 | if err != nil { |
| 127 | return nil, 0, err |
| 128 | } |
| 129 | |
| 130 | checksum := common.Checksum(buf) |
| 131 | if checksum != hdr.Checksum { |
| 132 | return nil, 0, fmt.Errorf("message checksum mismatch: %x != %x ", hdr.Checksum, checksum) |
| 133 | } |
| 134 | |
| 135 | cmdType := string(bytes.TrimRight(hdr.CMD[:], string(0))) |
| 136 | msg, err := MakeEmptyMessage(cmdType) |
| 137 | if err != nil { |
| 138 | return nil, 0, err |
| 139 | } |
| 140 | |
| 141 | // the buf is referenced by msg to avoid reallocation, so can not reused |
| 142 | source := comm.NewZeroCopySource(buf) |
| 143 | err = msg.Deserialization(source) |
| 144 | if err != nil { |
| 145 | return nil, 0, err |
| 146 | } |
| 147 | |
| 148 | return msg, hdr.Length, nil |
| 149 | } |
| 150 | |
| 151 | func MakeEmptyMessage(cmdType string) (Message, error) { |
| 152 | switch cmdType { |