mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-07 14:54:15 +00:00
Add (de)serialization support for reject messages.
This commit is contained in:
parent
843fa633f3
commit
74d611218b
@ -70,6 +70,7 @@ public class BitcoinSerializer {
|
|||||||
names.put(FilteredBlock.class, "merkleblock");
|
names.put(FilteredBlock.class, "merkleblock");
|
||||||
names.put(NotFoundMessage.class, "notfound");
|
names.put(NotFoundMessage.class, "notfound");
|
||||||
names.put(MemoryPoolMessage.class, "mempool");
|
names.put(MemoryPoolMessage.class, "mempool");
|
||||||
|
names.put(RejectMessage.class, "reject");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -231,6 +232,8 @@ public class BitcoinSerializer {
|
|||||||
return new NotFoundMessage(params, payloadBytes);
|
return new NotFoundMessage(params, payloadBytes);
|
||||||
} else if (command.equals("mempool")) {
|
} else if (command.equals("mempool")) {
|
||||||
return new MemoryPoolMessage();
|
return new MemoryPoolMessage();
|
||||||
|
} else if (command.equals("reject")) {
|
||||||
|
return new RejectMessage(params, payloadBytes);
|
||||||
} else {
|
} else {
|
||||||
log.warn("No support for deserializing message with name {}", command);
|
log.warn("No support for deserializing message with name {}", command);
|
||||||
return new UnknownMessage(params, command, payloadBytes);
|
return new UnknownMessage(params, command, payloadBytes);
|
||||||
|
152
core/src/main/java/com/google/bitcoin/core/RejectMessage.java
Normal file
152
core/src/main/java/com/google/bitcoin/core/RejectMessage.java
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2013 Matt Corallo
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.bitcoin.core;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A message sent by nodes when a message we sent was rejected (ie a transaction had too little fee/was invalid/etc)
|
||||||
|
*/
|
||||||
|
public class RejectMessage extends Message {
|
||||||
|
private static final long serialVersionUID = -5246995579800334336L;
|
||||||
|
|
||||||
|
private String message, reason;
|
||||||
|
public static enum RejectCode {
|
||||||
|
/** The message was not able to be parsed */
|
||||||
|
MALFORMED((byte) 0x01),
|
||||||
|
/** The message described an invalid object */
|
||||||
|
INVALID((byte) 0x10),
|
||||||
|
/** The message was obsolete or described an object which is obsolete (eg unsupported, old version, v1 block) */
|
||||||
|
OBSOLETE((byte) 0x11),
|
||||||
|
/**
|
||||||
|
* The message was relayed multiple times or described an object which is in conflict with another.
|
||||||
|
* This message can describe errors in protocol implementation or the presence of an attempt to DOUBLE SPEND.
|
||||||
|
*/
|
||||||
|
DUPLICATE((byte) 0x12),
|
||||||
|
/**
|
||||||
|
* The message described an object was not standard and was thus not accepted.
|
||||||
|
* The reference client has a concept of standard transaction forms, which describe scripts and encodings which
|
||||||
|
* it is willing to relay further. Other transactions are neither relayed nor mined, though they are considered
|
||||||
|
* valid if they appear in a block.
|
||||||
|
*/
|
||||||
|
NONSTANDARD((byte) 0x40),
|
||||||
|
/**
|
||||||
|
* This refers to a specific form of NONSTANDARD transactions, which have an output smaller than some constant
|
||||||
|
* defining them as dust (this is no longer used).
|
||||||
|
*/
|
||||||
|
DUST((byte) 0x41),
|
||||||
|
/** The messages described an object which did not have sufficient fee to be relayed further. */
|
||||||
|
INSUFFICIENTFEE((byte) 0x42),
|
||||||
|
/** The message described a block which was invalid according to hard-coded checkpoint blocks. */
|
||||||
|
CHECKPOINT((byte) 0x43),
|
||||||
|
OTHER((byte) 0xff);
|
||||||
|
|
||||||
|
byte code;
|
||||||
|
RejectCode(byte code) { this.code = code; }
|
||||||
|
static RejectCode fromCode(byte code) {
|
||||||
|
for (RejectCode rejectCode : RejectCode.values())
|
||||||
|
if (rejectCode.code == code)
|
||||||
|
return rejectCode;
|
||||||
|
return OTHER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private RejectCode code;
|
||||||
|
private Sha256Hash messageHash;
|
||||||
|
|
||||||
|
public RejectMessage(NetworkParameters params, byte[] bytes) throws ProtocolException {
|
||||||
|
super(params, bytes, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RejectMessage(NetworkParameters params, byte[] msg, boolean parseLazy, boolean parseRetain, int length)
|
||||||
|
throws ProtocolException {
|
||||||
|
super(params, msg, 0, parseLazy, parseRetain, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void parseLite() throws ProtocolException {
|
||||||
|
message = readStr();
|
||||||
|
code = RejectCode.fromCode(readBytes(1)[0]);
|
||||||
|
reason = readStr();
|
||||||
|
if (message.equals("block") || message.equals("tx"))
|
||||||
|
messageHash = readHash();
|
||||||
|
length = cursor - offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void parse() throws ProtocolException {
|
||||||
|
if (length == UNKNOWN_LENGTH)
|
||||||
|
parseLite();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bitcoinSerializeToStream(OutputStream stream) throws IOException {
|
||||||
|
byte[] messageBytes = message.getBytes("UTF-8");
|
||||||
|
stream.write(new VarInt(messageBytes.length).encode());
|
||||||
|
stream.write(messageBytes);
|
||||||
|
stream.write(code.code);
|
||||||
|
byte[] reasonBytes = reason.getBytes("UTF-8");
|
||||||
|
stream.write(new VarInt(reasonBytes.length).encode());
|
||||||
|
stream.write(reasonBytes);
|
||||||
|
if (message.equals("block") || message.equals("tx"))
|
||||||
|
stream.write(messageHash.getBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the type of message which was rejected by the peer.
|
||||||
|
* Note that this is ENTIRELY UNTRUSTED and should be sanity-checked before it is printed or processed.
|
||||||
|
*/
|
||||||
|
public String getRejectedMessage() {
|
||||||
|
ensureParsed();
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the hash of the rejected object (if getRejectedMessage() is either "tx" or "block"), otherwise null.
|
||||||
|
*/
|
||||||
|
public Sha256Hash getRejectedObjectHash() {
|
||||||
|
ensureParsed();
|
||||||
|
return messageHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The reason code given for why the peer rejected the message.
|
||||||
|
*/
|
||||||
|
public RejectCode getReasonCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The reason message given for rejection.
|
||||||
|
* Note that this is ENTIRELY UNTRUSTED and should be sanity-checked before it is printed or processed.
|
||||||
|
*/
|
||||||
|
public String getReasonString() {
|
||||||
|
return reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
return o instanceof RejectMessage &&
|
||||||
|
((RejectMessage) o).message.equals(message) &&
|
||||||
|
((RejectMessage) o).code.equals(code) &&
|
||||||
|
((RejectMessage) o).reason.equals(reason) &&
|
||||||
|
((RejectMessage) o).messageHash.equals(messageHash);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user