diff --git a/WindowsInstaller/Qortal.aip b/WindowsInstaller/Qortal.aip index 06643cca..74acc012 100755 --- a/WindowsInstaller/Qortal.aip +++ b/WindowsInstaller/Qortal.aip @@ -17,10 +17,10 @@ - + - + @@ -212,7 +212,7 @@ - + diff --git a/pom.xml b/pom.xml index 9e7c9741..22017136 100644 --- a/pom.xml +++ b/pom.xml @@ -3,13 +3,13 @@ 4.0.0 org.qortal qortal - 3.4.1 + 3.5.0 jar true - 6628cfd + 7dc8c6f 0.15.10 - 1.64 + 1.69 ${maven.build.timestamp} 1.3.8 3.6 @@ -34,6 +34,8 @@ 1.1.0 1.13.1 4.10 + 1.45.1 + 3.19.4 src/main/java @@ -705,5 +707,25 @@ java-diff-utils ${java-diff-utils.version} + + io.grpc + grpc-netty + ${grpc.version} + + + io.grpc + grpc-protobuf + ${grpc.version} + + + io.grpc + grpc-stub + ${grpc.version} + + + com.google.protobuf + protobuf-java + ${protobuf.version} + diff --git a/src/main/java/cash/z/wallet/sdk/rpc/CompactFormats.java b/src/main/java/cash/z/wallet/sdk/rpc/CompactFormats.java new file mode 100644 index 00000000..7ab80569 --- /dev/null +++ b/src/main/java/cash/z/wallet/sdk/rpc/CompactFormats.java @@ -0,0 +1,4499 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: compact_formats.proto + +package cash.z.wallet.sdk.rpc; + +public final class CompactFormats { + private CompactFormats() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistryLite registry) { + } + + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + registerAllExtensions( + (com.google.protobuf.ExtensionRegistryLite) registry); + } + public interface CompactBlockOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.CompactBlock) + com.google.protobuf.MessageOrBuilder { + + /** + *
+     * the version of this wire format, for storage
+     * 
+ * + * uint32 protoVersion = 1; + * @return The protoVersion. + */ + int getProtoVersion(); + + /** + *
+     * the height of this block
+     * 
+ * + * uint64 height = 2; + * @return The height. + */ + long getHeight(); + + /** + *
+     * the ID (hash) of this block, same as in block explorers
+     * 
+ * + * bytes hash = 3; + * @return The hash. + */ + com.google.protobuf.ByteString getHash(); + + /** + *
+     * the ID (hash) of this block's predecessor
+     * 
+ * + * bytes prevHash = 4; + * @return The prevHash. + */ + com.google.protobuf.ByteString getPrevHash(); + + /** + *
+     * Unix epoch time when the block was mined
+     * 
+ * + * uint32 time = 5; + * @return The time. + */ + int getTime(); + + /** + *
+     * (hash, prevHash, and time) OR (full header)
+     * 
+ * + * bytes header = 6; + * @return The header. + */ + com.google.protobuf.ByteString getHeader(); + + /** + *
+     * zero or more compact transactions from this block
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + java.util.List + getVtxList(); + /** + *
+     * zero or more compact transactions from this block
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + cash.z.wallet.sdk.rpc.CompactFormats.CompactTx getVtx(int index); + /** + *
+     * zero or more compact transactions from this block
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + int getVtxCount(); + /** + *
+     * zero or more compact transactions from this block
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + java.util.List + getVtxOrBuilderList(); + /** + *
+     * zero or more compact transactions from this block
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + cash.z.wallet.sdk.rpc.CompactFormats.CompactTxOrBuilder getVtxOrBuilder( + int index); + } + /** + *
+   * CompactBlock is a packaging of ONLY the data from a block that's needed to:
+   *   1. Detect a payment to your shielded Sapling address
+   *   2. Detect a spend of your shielded Sapling notes
+   *   3. Update your witnesses to generate new Sapling spend proofs.
+   * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.CompactBlock} + */ + public static final class CompactBlock extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.CompactBlock) + CompactBlockOrBuilder { + private static final long serialVersionUID = 0L; + // Use CompactBlock.newBuilder() to construct. + private CompactBlock(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private CompactBlock() { + hash_ = com.google.protobuf.ByteString.EMPTY; + prevHash_ = com.google.protobuf.ByteString.EMPTY; + header_ = com.google.protobuf.ByteString.EMPTY; + vtx_ = java.util.Collections.emptyList(); + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new CompactBlock(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private CompactBlock( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: { + + protoVersion_ = input.readUInt32(); + break; + } + case 16: { + + height_ = input.readUInt64(); + break; + } + case 26: { + + hash_ = input.readBytes(); + break; + } + case 34: { + + prevHash_ = input.readBytes(); + break; + } + case 40: { + + time_ = input.readUInt32(); + break; + } + case 50: { + + header_ = input.readBytes(); + break; + } + case 58: { + if (!((mutable_bitField0_ & 0x00000001) != 0)) { + vtx_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000001; + } + vtx_.add( + input.readMessage(cash.z.wallet.sdk.rpc.CompactFormats.CompactTx.parser(), extensionRegistry)); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) != 0)) { + vtx_ = java.util.Collections.unmodifiableList(vtx_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.CompactFormats.internal_static_cash_z_wallet_sdk_rpc_CompactBlock_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.CompactFormats.internal_static_cash_z_wallet_sdk_rpc_CompactBlock_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock.class, cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock.Builder.class); + } + + public static final int PROTOVERSION_FIELD_NUMBER = 1; + private int protoVersion_; + /** + *
+     * the version of this wire format, for storage
+     * 
+ * + * uint32 protoVersion = 1; + * @return The protoVersion. + */ + @java.lang.Override + public int getProtoVersion() { + return protoVersion_; + } + + public static final int HEIGHT_FIELD_NUMBER = 2; + private long height_; + /** + *
+     * the height of this block
+     * 
+ * + * uint64 height = 2; + * @return The height. + */ + @java.lang.Override + public long getHeight() { + return height_; + } + + public static final int HASH_FIELD_NUMBER = 3; + private com.google.protobuf.ByteString hash_; + /** + *
+     * the ID (hash) of this block, same as in block explorers
+     * 
+ * + * bytes hash = 3; + * @return The hash. + */ + @java.lang.Override + public com.google.protobuf.ByteString getHash() { + return hash_; + } + + public static final int PREVHASH_FIELD_NUMBER = 4; + private com.google.protobuf.ByteString prevHash_; + /** + *
+     * the ID (hash) of this block's predecessor
+     * 
+ * + * bytes prevHash = 4; + * @return The prevHash. + */ + @java.lang.Override + public com.google.protobuf.ByteString getPrevHash() { + return prevHash_; + } + + public static final int TIME_FIELD_NUMBER = 5; + private int time_; + /** + *
+     * Unix epoch time when the block was mined
+     * 
+ * + * uint32 time = 5; + * @return The time. + */ + @java.lang.Override + public int getTime() { + return time_; + } + + public static final int HEADER_FIELD_NUMBER = 6; + private com.google.protobuf.ByteString header_; + /** + *
+     * (hash, prevHash, and time) OR (full header)
+     * 
+ * + * bytes header = 6; + * @return The header. + */ + @java.lang.Override + public com.google.protobuf.ByteString getHeader() { + return header_; + } + + public static final int VTX_FIELD_NUMBER = 7; + private java.util.List vtx_; + /** + *
+     * zero or more compact transactions from this block
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + @java.lang.Override + public java.util.List getVtxList() { + return vtx_; + } + /** + *
+     * zero or more compact transactions from this block
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + @java.lang.Override + public java.util.List + getVtxOrBuilderList() { + return vtx_; + } + /** + *
+     * zero or more compact transactions from this block
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + @java.lang.Override + public int getVtxCount() { + return vtx_.size(); + } + /** + *
+     * zero or more compact transactions from this block
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + @java.lang.Override + public cash.z.wallet.sdk.rpc.CompactFormats.CompactTx getVtx(int index) { + return vtx_.get(index); + } + /** + *
+     * zero or more compact transactions from this block
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + @java.lang.Override + public cash.z.wallet.sdk.rpc.CompactFormats.CompactTxOrBuilder getVtxOrBuilder( + int index) { + return vtx_.get(index); + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (protoVersion_ != 0) { + output.writeUInt32(1, protoVersion_); + } + if (height_ != 0L) { + output.writeUInt64(2, height_); + } + if (!hash_.isEmpty()) { + output.writeBytes(3, hash_); + } + if (!prevHash_.isEmpty()) { + output.writeBytes(4, prevHash_); + } + if (time_ != 0) { + output.writeUInt32(5, time_); + } + if (!header_.isEmpty()) { + output.writeBytes(6, header_); + } + for (int i = 0; i < vtx_.size(); i++) { + output.writeMessage(7, vtx_.get(i)); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (protoVersion_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeUInt32Size(1, protoVersion_); + } + if (height_ != 0L) { + size += com.google.protobuf.CodedOutputStream + .computeUInt64Size(2, height_); + } + if (!hash_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, hash_); + } + if (!prevHash_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(4, prevHash_); + } + if (time_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeUInt32Size(5, time_); + } + if (!header_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(6, header_); + } + for (int i = 0; i < vtx_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(7, vtx_.get(i)); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock other = (cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock) obj; + + if (getProtoVersion() + != other.getProtoVersion()) return false; + if (getHeight() + != other.getHeight()) return false; + if (!getHash() + .equals(other.getHash())) return false; + if (!getPrevHash() + .equals(other.getPrevHash())) return false; + if (getTime() + != other.getTime()) return false; + if (!getHeader() + .equals(other.getHeader())) return false; + if (!getVtxList() + .equals(other.getVtxList())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + PROTOVERSION_FIELD_NUMBER; + hash = (53 * hash) + getProtoVersion(); + hash = (37 * hash) + HEIGHT_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashLong( + getHeight()); + hash = (37 * hash) + HASH_FIELD_NUMBER; + hash = (53 * hash) + getHash().hashCode(); + hash = (37 * hash) + PREVHASH_FIELD_NUMBER; + hash = (53 * hash) + getPrevHash().hashCode(); + hash = (37 * hash) + TIME_FIELD_NUMBER; + hash = (53 * hash) + getTime(); + hash = (37 * hash) + HEADER_FIELD_NUMBER; + hash = (53 * hash) + getHeader().hashCode(); + if (getVtxCount() > 0) { + hash = (37 * hash) + VTX_FIELD_NUMBER; + hash = (53 * hash) + getVtxList().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * CompactBlock is a packaging of ONLY the data from a block that's needed to:
+     *   1. Detect a payment to your shielded Sapling address
+     *   2. Detect a spend of your shielded Sapling notes
+     *   3. Update your witnesses to generate new Sapling spend proofs.
+     * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.CompactBlock} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.CompactBlock) + cash.z.wallet.sdk.rpc.CompactFormats.CompactBlockOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.CompactFormats.internal_static_cash_z_wallet_sdk_rpc_CompactBlock_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.CompactFormats.internal_static_cash_z_wallet_sdk_rpc_CompactBlock_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock.class, cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getVtxFieldBuilder(); + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + protoVersion_ = 0; + + height_ = 0L; + + hash_ = com.google.protobuf.ByteString.EMPTY; + + prevHash_ = com.google.protobuf.ByteString.EMPTY; + + time_ = 0; + + header_ = com.google.protobuf.ByteString.EMPTY; + + if (vtxBuilder_ == null) { + vtx_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + } else { + vtxBuilder_.clear(); + } + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.CompactFormats.internal_static_cash_z_wallet_sdk_rpc_CompactBlock_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock build() { + cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock buildPartial() { + cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock result = new cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock(this); + int from_bitField0_ = bitField0_; + result.protoVersion_ = protoVersion_; + result.height_ = height_; + result.hash_ = hash_; + result.prevHash_ = prevHash_; + result.time_ = time_; + result.header_ = header_; + if (vtxBuilder_ == null) { + if (((bitField0_ & 0x00000001) != 0)) { + vtx_ = java.util.Collections.unmodifiableList(vtx_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.vtx_ = vtx_; + } else { + result.vtx_ = vtxBuilder_.build(); + } + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock) { + return mergeFrom((cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock other) { + if (other == cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock.getDefaultInstance()) return this; + if (other.getProtoVersion() != 0) { + setProtoVersion(other.getProtoVersion()); + } + if (other.getHeight() != 0L) { + setHeight(other.getHeight()); + } + if (other.getHash() != com.google.protobuf.ByteString.EMPTY) { + setHash(other.getHash()); + } + if (other.getPrevHash() != com.google.protobuf.ByteString.EMPTY) { + setPrevHash(other.getPrevHash()); + } + if (other.getTime() != 0) { + setTime(other.getTime()); + } + if (other.getHeader() != com.google.protobuf.ByteString.EMPTY) { + setHeader(other.getHeader()); + } + if (vtxBuilder_ == null) { + if (!other.vtx_.isEmpty()) { + if (vtx_.isEmpty()) { + vtx_ = other.vtx_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureVtxIsMutable(); + vtx_.addAll(other.vtx_); + } + onChanged(); + } + } else { + if (!other.vtx_.isEmpty()) { + if (vtxBuilder_.isEmpty()) { + vtxBuilder_.dispose(); + vtxBuilder_ = null; + vtx_ = other.vtx_; + bitField0_ = (bitField0_ & ~0x00000001); + vtxBuilder_ = + com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ? + getVtxFieldBuilder() : null; + } else { + vtxBuilder_.addAllMessages(other.vtx_); + } + } + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private int protoVersion_ ; + /** + *
+       * the version of this wire format, for storage
+       * 
+ * + * uint32 protoVersion = 1; + * @return The protoVersion. + */ + @java.lang.Override + public int getProtoVersion() { + return protoVersion_; + } + /** + *
+       * the version of this wire format, for storage
+       * 
+ * + * uint32 protoVersion = 1; + * @param value The protoVersion to set. + * @return This builder for chaining. + */ + public Builder setProtoVersion(int value) { + + protoVersion_ = value; + onChanged(); + return this; + } + /** + *
+       * the version of this wire format, for storage
+       * 
+ * + * uint32 protoVersion = 1; + * @return This builder for chaining. + */ + public Builder clearProtoVersion() { + + protoVersion_ = 0; + onChanged(); + return this; + } + + private long height_ ; + /** + *
+       * the height of this block
+       * 
+ * + * uint64 height = 2; + * @return The height. + */ + @java.lang.Override + public long getHeight() { + return height_; + } + /** + *
+       * the height of this block
+       * 
+ * + * uint64 height = 2; + * @param value The height to set. + * @return This builder for chaining. + */ + public Builder setHeight(long value) { + + height_ = value; + onChanged(); + return this; + } + /** + *
+       * the height of this block
+       * 
+ * + * uint64 height = 2; + * @return This builder for chaining. + */ + public Builder clearHeight() { + + height_ = 0L; + onChanged(); + return this; + } + + private com.google.protobuf.ByteString hash_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+       * the ID (hash) of this block, same as in block explorers
+       * 
+ * + * bytes hash = 3; + * @return The hash. + */ + @java.lang.Override + public com.google.protobuf.ByteString getHash() { + return hash_; + } + /** + *
+       * the ID (hash) of this block, same as in block explorers
+       * 
+ * + * bytes hash = 3; + * @param value The hash to set. + * @return This builder for chaining. + */ + public Builder setHash(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + + hash_ = value; + onChanged(); + return this; + } + /** + *
+       * the ID (hash) of this block, same as in block explorers
+       * 
+ * + * bytes hash = 3; + * @return This builder for chaining. + */ + public Builder clearHash() { + + hash_ = getDefaultInstance().getHash(); + onChanged(); + return this; + } + + private com.google.protobuf.ByteString prevHash_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+       * the ID (hash) of this block's predecessor
+       * 
+ * + * bytes prevHash = 4; + * @return The prevHash. + */ + @java.lang.Override + public com.google.protobuf.ByteString getPrevHash() { + return prevHash_; + } + /** + *
+       * the ID (hash) of this block's predecessor
+       * 
+ * + * bytes prevHash = 4; + * @param value The prevHash to set. + * @return This builder for chaining. + */ + public Builder setPrevHash(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + + prevHash_ = value; + onChanged(); + return this; + } + /** + *
+       * the ID (hash) of this block's predecessor
+       * 
+ * + * bytes prevHash = 4; + * @return This builder for chaining. + */ + public Builder clearPrevHash() { + + prevHash_ = getDefaultInstance().getPrevHash(); + onChanged(); + return this; + } + + private int time_ ; + /** + *
+       * Unix epoch time when the block was mined
+       * 
+ * + * uint32 time = 5; + * @return The time. + */ + @java.lang.Override + public int getTime() { + return time_; + } + /** + *
+       * Unix epoch time when the block was mined
+       * 
+ * + * uint32 time = 5; + * @param value The time to set. + * @return This builder for chaining. + */ + public Builder setTime(int value) { + + time_ = value; + onChanged(); + return this; + } + /** + *
+       * Unix epoch time when the block was mined
+       * 
+ * + * uint32 time = 5; + * @return This builder for chaining. + */ + public Builder clearTime() { + + time_ = 0; + onChanged(); + return this; + } + + private com.google.protobuf.ByteString header_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+       * (hash, prevHash, and time) OR (full header)
+       * 
+ * + * bytes header = 6; + * @return The header. + */ + @java.lang.Override + public com.google.protobuf.ByteString getHeader() { + return header_; + } + /** + *
+       * (hash, prevHash, and time) OR (full header)
+       * 
+ * + * bytes header = 6; + * @param value The header to set. + * @return This builder for chaining. + */ + public Builder setHeader(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + + header_ = value; + onChanged(); + return this; + } + /** + *
+       * (hash, prevHash, and time) OR (full header)
+       * 
+ * + * bytes header = 6; + * @return This builder for chaining. + */ + public Builder clearHeader() { + + header_ = getDefaultInstance().getHeader(); + onChanged(); + return this; + } + + private java.util.List vtx_ = + java.util.Collections.emptyList(); + private void ensureVtxIsMutable() { + if (!((bitField0_ & 0x00000001) != 0)) { + vtx_ = new java.util.ArrayList(vtx_); + bitField0_ |= 0x00000001; + } + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + cash.z.wallet.sdk.rpc.CompactFormats.CompactTx, cash.z.wallet.sdk.rpc.CompactFormats.CompactTx.Builder, cash.z.wallet.sdk.rpc.CompactFormats.CompactTxOrBuilder> vtxBuilder_; + + /** + *
+       * zero or more compact transactions from this block
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + public java.util.List getVtxList() { + if (vtxBuilder_ == null) { + return java.util.Collections.unmodifiableList(vtx_); + } else { + return vtxBuilder_.getMessageList(); + } + } + /** + *
+       * zero or more compact transactions from this block
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + public int getVtxCount() { + if (vtxBuilder_ == null) { + return vtx_.size(); + } else { + return vtxBuilder_.getCount(); + } + } + /** + *
+       * zero or more compact transactions from this block
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + public cash.z.wallet.sdk.rpc.CompactFormats.CompactTx getVtx(int index) { + if (vtxBuilder_ == null) { + return vtx_.get(index); + } else { + return vtxBuilder_.getMessage(index); + } + } + /** + *
+       * zero or more compact transactions from this block
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + public Builder setVtx( + int index, cash.z.wallet.sdk.rpc.CompactFormats.CompactTx value) { + if (vtxBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureVtxIsMutable(); + vtx_.set(index, value); + onChanged(); + } else { + vtxBuilder_.setMessage(index, value); + } + return this; + } + /** + *
+       * zero or more compact transactions from this block
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + public Builder setVtx( + int index, cash.z.wallet.sdk.rpc.CompactFormats.CompactTx.Builder builderForValue) { + if (vtxBuilder_ == null) { + ensureVtxIsMutable(); + vtx_.set(index, builderForValue.build()); + onChanged(); + } else { + vtxBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + *
+       * zero or more compact transactions from this block
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + public Builder addVtx(cash.z.wallet.sdk.rpc.CompactFormats.CompactTx value) { + if (vtxBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureVtxIsMutable(); + vtx_.add(value); + onChanged(); + } else { + vtxBuilder_.addMessage(value); + } + return this; + } + /** + *
+       * zero or more compact transactions from this block
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + public Builder addVtx( + int index, cash.z.wallet.sdk.rpc.CompactFormats.CompactTx value) { + if (vtxBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureVtxIsMutable(); + vtx_.add(index, value); + onChanged(); + } else { + vtxBuilder_.addMessage(index, value); + } + return this; + } + /** + *
+       * zero or more compact transactions from this block
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + public Builder addVtx( + cash.z.wallet.sdk.rpc.CompactFormats.CompactTx.Builder builderForValue) { + if (vtxBuilder_ == null) { + ensureVtxIsMutable(); + vtx_.add(builderForValue.build()); + onChanged(); + } else { + vtxBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + *
+       * zero or more compact transactions from this block
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + public Builder addVtx( + int index, cash.z.wallet.sdk.rpc.CompactFormats.CompactTx.Builder builderForValue) { + if (vtxBuilder_ == null) { + ensureVtxIsMutable(); + vtx_.add(index, builderForValue.build()); + onChanged(); + } else { + vtxBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + *
+       * zero or more compact transactions from this block
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + public Builder addAllVtx( + java.lang.Iterable values) { + if (vtxBuilder_ == null) { + ensureVtxIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, vtx_); + onChanged(); + } else { + vtxBuilder_.addAllMessages(values); + } + return this; + } + /** + *
+       * zero or more compact transactions from this block
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + public Builder clearVtx() { + if (vtxBuilder_ == null) { + vtx_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + } else { + vtxBuilder_.clear(); + } + return this; + } + /** + *
+       * zero or more compact transactions from this block
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + public Builder removeVtx(int index) { + if (vtxBuilder_ == null) { + ensureVtxIsMutable(); + vtx_.remove(index); + onChanged(); + } else { + vtxBuilder_.remove(index); + } + return this; + } + /** + *
+       * zero or more compact transactions from this block
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + public cash.z.wallet.sdk.rpc.CompactFormats.CompactTx.Builder getVtxBuilder( + int index) { + return getVtxFieldBuilder().getBuilder(index); + } + /** + *
+       * zero or more compact transactions from this block
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + public cash.z.wallet.sdk.rpc.CompactFormats.CompactTxOrBuilder getVtxOrBuilder( + int index) { + if (vtxBuilder_ == null) { + return vtx_.get(index); } else { + return vtxBuilder_.getMessageOrBuilder(index); + } + } + /** + *
+       * zero or more compact transactions from this block
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + public java.util.List + getVtxOrBuilderList() { + if (vtxBuilder_ != null) { + return vtxBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(vtx_); + } + } + /** + *
+       * zero or more compact transactions from this block
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + public cash.z.wallet.sdk.rpc.CompactFormats.CompactTx.Builder addVtxBuilder() { + return getVtxFieldBuilder().addBuilder( + cash.z.wallet.sdk.rpc.CompactFormats.CompactTx.getDefaultInstance()); + } + /** + *
+       * zero or more compact transactions from this block
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + public cash.z.wallet.sdk.rpc.CompactFormats.CompactTx.Builder addVtxBuilder( + int index) { + return getVtxFieldBuilder().addBuilder( + index, cash.z.wallet.sdk.rpc.CompactFormats.CompactTx.getDefaultInstance()); + } + /** + *
+       * zero or more compact transactions from this block
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactTx vtx = 7; + */ + public java.util.List + getVtxBuilderList() { + return getVtxFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilderV3< + cash.z.wallet.sdk.rpc.CompactFormats.CompactTx, cash.z.wallet.sdk.rpc.CompactFormats.CompactTx.Builder, cash.z.wallet.sdk.rpc.CompactFormats.CompactTxOrBuilder> + getVtxFieldBuilder() { + if (vtxBuilder_ == null) { + vtxBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3< + cash.z.wallet.sdk.rpc.CompactFormats.CompactTx, cash.z.wallet.sdk.rpc.CompactFormats.CompactTx.Builder, cash.z.wallet.sdk.rpc.CompactFormats.CompactTxOrBuilder>( + vtx_, + ((bitField0_ & 0x00000001) != 0), + getParentForChildren(), + isClean()); + vtx_ = null; + } + return vtxBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.CompactBlock) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.CompactBlock) + private static final cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock(); + } + + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public CompactBlock parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new CompactBlock(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface CompactTxOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.CompactTx) + com.google.protobuf.MessageOrBuilder { + + /** + *
+     * the index within the full block
+     * 
+ * + * uint64 index = 1; + * @return The index. + */ + long getIndex(); + + /** + *
+     * the ID (hash) of this transaction, same as in block explorers
+     * 
+ * + * bytes hash = 2; + * @return The hash. + */ + com.google.protobuf.ByteString getHash(); + + /** + *
+     * The transaction fee: present if server can provide. In the case of a
+     * stateless server and a transaction with transparent inputs, this will be
+     * unset because the calculation requires reference to prior transactions.
+     * in a pure-Sapling context, the fee will be calculable as:
+     *    valueBalance + (sum(vPubNew) - sum(vPubOld) - sum(tOut))
+     * 
+ * + * uint32 fee = 3; + * @return The fee. + */ + int getFee(); + + /** + *
+     * inputs
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + java.util.List + getSpendsList(); + /** + *
+     * inputs
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend getSpends(int index); + /** + *
+     * inputs
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + int getSpendsCount(); + /** + *
+     * inputs
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + java.util.List + getSpendsOrBuilderList(); + /** + *
+     * inputs
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + cash.z.wallet.sdk.rpc.CompactFormats.CompactSpendOrBuilder getSpendsOrBuilder( + int index); + + /** + *
+     * outputs
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + java.util.List + getOutputsList(); + /** + *
+     * outputs
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput getOutputs(int index); + /** + *
+     * outputs
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + int getOutputsCount(); + /** + *
+     * outputs
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + java.util.List + getOutputsOrBuilderList(); + /** + *
+     * outputs
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + cash.z.wallet.sdk.rpc.CompactFormats.CompactOutputOrBuilder getOutputsOrBuilder( + int index); + } + /** + *
+   * CompactTx contains the minimum information for a wallet to know if this transaction
+   * is relevant to it (either pays to it or spends from it) via shielded elements
+   * only. This message will not encode a transparent-to-transparent transaction.
+   * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.CompactTx} + */ + public static final class CompactTx extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.CompactTx) + CompactTxOrBuilder { + private static final long serialVersionUID = 0L; + // Use CompactTx.newBuilder() to construct. + private CompactTx(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private CompactTx() { + hash_ = com.google.protobuf.ByteString.EMPTY; + spends_ = java.util.Collections.emptyList(); + outputs_ = java.util.Collections.emptyList(); + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new CompactTx(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private CompactTx( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: { + + index_ = input.readUInt64(); + break; + } + case 18: { + + hash_ = input.readBytes(); + break; + } + case 24: { + + fee_ = input.readUInt32(); + break; + } + case 34: { + if (!((mutable_bitField0_ & 0x00000001) != 0)) { + spends_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000001; + } + spends_.add( + input.readMessage(cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend.parser(), extensionRegistry)); + break; + } + case 42: { + if (!((mutable_bitField0_ & 0x00000002) != 0)) { + outputs_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000002; + } + outputs_.add( + input.readMessage(cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput.parser(), extensionRegistry)); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) != 0)) { + spends_ = java.util.Collections.unmodifiableList(spends_); + } + if (((mutable_bitField0_ & 0x00000002) != 0)) { + outputs_ = java.util.Collections.unmodifiableList(outputs_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.CompactFormats.internal_static_cash_z_wallet_sdk_rpc_CompactTx_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.CompactFormats.internal_static_cash_z_wallet_sdk_rpc_CompactTx_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.CompactFormats.CompactTx.class, cash.z.wallet.sdk.rpc.CompactFormats.CompactTx.Builder.class); + } + + public static final int INDEX_FIELD_NUMBER = 1; + private long index_; + /** + *
+     * the index within the full block
+     * 
+ * + * uint64 index = 1; + * @return The index. + */ + @java.lang.Override + public long getIndex() { + return index_; + } + + public static final int HASH_FIELD_NUMBER = 2; + private com.google.protobuf.ByteString hash_; + /** + *
+     * the ID (hash) of this transaction, same as in block explorers
+     * 
+ * + * bytes hash = 2; + * @return The hash. + */ + @java.lang.Override + public com.google.protobuf.ByteString getHash() { + return hash_; + } + + public static final int FEE_FIELD_NUMBER = 3; + private int fee_; + /** + *
+     * The transaction fee: present if server can provide. In the case of a
+     * stateless server and a transaction with transparent inputs, this will be
+     * unset because the calculation requires reference to prior transactions.
+     * in a pure-Sapling context, the fee will be calculable as:
+     *    valueBalance + (sum(vPubNew) - sum(vPubOld) - sum(tOut))
+     * 
+ * + * uint32 fee = 3; + * @return The fee. + */ + @java.lang.Override + public int getFee() { + return fee_; + } + + public static final int SPENDS_FIELD_NUMBER = 4; + private java.util.List spends_; + /** + *
+     * inputs
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + @java.lang.Override + public java.util.List getSpendsList() { + return spends_; + } + /** + *
+     * inputs
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + @java.lang.Override + public java.util.List + getSpendsOrBuilderList() { + return spends_; + } + /** + *
+     * inputs
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + @java.lang.Override + public int getSpendsCount() { + return spends_.size(); + } + /** + *
+     * inputs
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + @java.lang.Override + public cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend getSpends(int index) { + return spends_.get(index); + } + /** + *
+     * inputs
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + @java.lang.Override + public cash.z.wallet.sdk.rpc.CompactFormats.CompactSpendOrBuilder getSpendsOrBuilder( + int index) { + return spends_.get(index); + } + + public static final int OUTPUTS_FIELD_NUMBER = 5; + private java.util.List outputs_; + /** + *
+     * outputs
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + @java.lang.Override + public java.util.List getOutputsList() { + return outputs_; + } + /** + *
+     * outputs
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + @java.lang.Override + public java.util.List + getOutputsOrBuilderList() { + return outputs_; + } + /** + *
+     * outputs
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + @java.lang.Override + public int getOutputsCount() { + return outputs_.size(); + } + /** + *
+     * outputs
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + @java.lang.Override + public cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput getOutputs(int index) { + return outputs_.get(index); + } + /** + *
+     * outputs
+     * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + @java.lang.Override + public cash.z.wallet.sdk.rpc.CompactFormats.CompactOutputOrBuilder getOutputsOrBuilder( + int index) { + return outputs_.get(index); + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (index_ != 0L) { + output.writeUInt64(1, index_); + } + if (!hash_.isEmpty()) { + output.writeBytes(2, hash_); + } + if (fee_ != 0) { + output.writeUInt32(3, fee_); + } + for (int i = 0; i < spends_.size(); i++) { + output.writeMessage(4, spends_.get(i)); + } + for (int i = 0; i < outputs_.size(); i++) { + output.writeMessage(5, outputs_.get(i)); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (index_ != 0L) { + size += com.google.protobuf.CodedOutputStream + .computeUInt64Size(1, index_); + } + if (!hash_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, hash_); + } + if (fee_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeUInt32Size(3, fee_); + } + for (int i = 0; i < spends_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(4, spends_.get(i)); + } + for (int i = 0; i < outputs_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(5, outputs_.get(i)); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.CompactFormats.CompactTx)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.CompactFormats.CompactTx other = (cash.z.wallet.sdk.rpc.CompactFormats.CompactTx) obj; + + if (getIndex() + != other.getIndex()) return false; + if (!getHash() + .equals(other.getHash())) return false; + if (getFee() + != other.getFee()) return false; + if (!getSpendsList() + .equals(other.getSpendsList())) return false; + if (!getOutputsList() + .equals(other.getOutputsList())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + INDEX_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashLong( + getIndex()); + hash = (37 * hash) + HASH_FIELD_NUMBER; + hash = (53 * hash) + getHash().hashCode(); + hash = (37 * hash) + FEE_FIELD_NUMBER; + hash = (53 * hash) + getFee(); + if (getSpendsCount() > 0) { + hash = (37 * hash) + SPENDS_FIELD_NUMBER; + hash = (53 * hash) + getSpendsList().hashCode(); + } + if (getOutputsCount() > 0) { + hash = (37 * hash) + OUTPUTS_FIELD_NUMBER; + hash = (53 * hash) + getOutputsList().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactTx parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactTx parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactTx parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactTx parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactTx parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactTx parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactTx parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactTx parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactTx parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactTx parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactTx parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactTx parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.CompactFormats.CompactTx prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * CompactTx contains the minimum information for a wallet to know if this transaction
+     * is relevant to it (either pays to it or spends from it) via shielded elements
+     * only. This message will not encode a transparent-to-transparent transaction.
+     * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.CompactTx} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.CompactTx) + cash.z.wallet.sdk.rpc.CompactFormats.CompactTxOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.CompactFormats.internal_static_cash_z_wallet_sdk_rpc_CompactTx_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.CompactFormats.internal_static_cash_z_wallet_sdk_rpc_CompactTx_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.CompactFormats.CompactTx.class, cash.z.wallet.sdk.rpc.CompactFormats.CompactTx.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.CompactFormats.CompactTx.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getSpendsFieldBuilder(); + getOutputsFieldBuilder(); + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + index_ = 0L; + + hash_ = com.google.protobuf.ByteString.EMPTY; + + fee_ = 0; + + if (spendsBuilder_ == null) { + spends_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + } else { + spendsBuilder_.clear(); + } + if (outputsBuilder_ == null) { + outputs_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + } else { + outputsBuilder_.clear(); + } + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.CompactFormats.internal_static_cash_z_wallet_sdk_rpc_CompactTx_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.CompactFormats.CompactTx getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.CompactFormats.CompactTx.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.CompactFormats.CompactTx build() { + cash.z.wallet.sdk.rpc.CompactFormats.CompactTx result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.CompactFormats.CompactTx buildPartial() { + cash.z.wallet.sdk.rpc.CompactFormats.CompactTx result = new cash.z.wallet.sdk.rpc.CompactFormats.CompactTx(this); + int from_bitField0_ = bitField0_; + result.index_ = index_; + result.hash_ = hash_; + result.fee_ = fee_; + if (spendsBuilder_ == null) { + if (((bitField0_ & 0x00000001) != 0)) { + spends_ = java.util.Collections.unmodifiableList(spends_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.spends_ = spends_; + } else { + result.spends_ = spendsBuilder_.build(); + } + if (outputsBuilder_ == null) { + if (((bitField0_ & 0x00000002) != 0)) { + outputs_ = java.util.Collections.unmodifiableList(outputs_); + bitField0_ = (bitField0_ & ~0x00000002); + } + result.outputs_ = outputs_; + } else { + result.outputs_ = outputsBuilder_.build(); + } + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.CompactFormats.CompactTx) { + return mergeFrom((cash.z.wallet.sdk.rpc.CompactFormats.CompactTx)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.CompactFormats.CompactTx other) { + if (other == cash.z.wallet.sdk.rpc.CompactFormats.CompactTx.getDefaultInstance()) return this; + if (other.getIndex() != 0L) { + setIndex(other.getIndex()); + } + if (other.getHash() != com.google.protobuf.ByteString.EMPTY) { + setHash(other.getHash()); + } + if (other.getFee() != 0) { + setFee(other.getFee()); + } + if (spendsBuilder_ == null) { + if (!other.spends_.isEmpty()) { + if (spends_.isEmpty()) { + spends_ = other.spends_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureSpendsIsMutable(); + spends_.addAll(other.spends_); + } + onChanged(); + } + } else { + if (!other.spends_.isEmpty()) { + if (spendsBuilder_.isEmpty()) { + spendsBuilder_.dispose(); + spendsBuilder_ = null; + spends_ = other.spends_; + bitField0_ = (bitField0_ & ~0x00000001); + spendsBuilder_ = + com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ? + getSpendsFieldBuilder() : null; + } else { + spendsBuilder_.addAllMessages(other.spends_); + } + } + } + if (outputsBuilder_ == null) { + if (!other.outputs_.isEmpty()) { + if (outputs_.isEmpty()) { + outputs_ = other.outputs_; + bitField0_ = (bitField0_ & ~0x00000002); + } else { + ensureOutputsIsMutable(); + outputs_.addAll(other.outputs_); + } + onChanged(); + } + } else { + if (!other.outputs_.isEmpty()) { + if (outputsBuilder_.isEmpty()) { + outputsBuilder_.dispose(); + outputsBuilder_ = null; + outputs_ = other.outputs_; + bitField0_ = (bitField0_ & ~0x00000002); + outputsBuilder_ = + com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ? + getOutputsFieldBuilder() : null; + } else { + outputsBuilder_.addAllMessages(other.outputs_); + } + } + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.CompactFormats.CompactTx parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.CompactFormats.CompactTx) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private long index_ ; + /** + *
+       * the index within the full block
+       * 
+ * + * uint64 index = 1; + * @return The index. + */ + @java.lang.Override + public long getIndex() { + return index_; + } + /** + *
+       * the index within the full block
+       * 
+ * + * uint64 index = 1; + * @param value The index to set. + * @return This builder for chaining. + */ + public Builder setIndex(long value) { + + index_ = value; + onChanged(); + return this; + } + /** + *
+       * the index within the full block
+       * 
+ * + * uint64 index = 1; + * @return This builder for chaining. + */ + public Builder clearIndex() { + + index_ = 0L; + onChanged(); + return this; + } + + private com.google.protobuf.ByteString hash_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+       * the ID (hash) of this transaction, same as in block explorers
+       * 
+ * + * bytes hash = 2; + * @return The hash. + */ + @java.lang.Override + public com.google.protobuf.ByteString getHash() { + return hash_; + } + /** + *
+       * the ID (hash) of this transaction, same as in block explorers
+       * 
+ * + * bytes hash = 2; + * @param value The hash to set. + * @return This builder for chaining. + */ + public Builder setHash(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + + hash_ = value; + onChanged(); + return this; + } + /** + *
+       * the ID (hash) of this transaction, same as in block explorers
+       * 
+ * + * bytes hash = 2; + * @return This builder for chaining. + */ + public Builder clearHash() { + + hash_ = getDefaultInstance().getHash(); + onChanged(); + return this; + } + + private int fee_ ; + /** + *
+       * The transaction fee: present if server can provide. In the case of a
+       * stateless server and a transaction with transparent inputs, this will be
+       * unset because the calculation requires reference to prior transactions.
+       * in a pure-Sapling context, the fee will be calculable as:
+       *    valueBalance + (sum(vPubNew) - sum(vPubOld) - sum(tOut))
+       * 
+ * + * uint32 fee = 3; + * @return The fee. + */ + @java.lang.Override + public int getFee() { + return fee_; + } + /** + *
+       * The transaction fee: present if server can provide. In the case of a
+       * stateless server and a transaction with transparent inputs, this will be
+       * unset because the calculation requires reference to prior transactions.
+       * in a pure-Sapling context, the fee will be calculable as:
+       *    valueBalance + (sum(vPubNew) - sum(vPubOld) - sum(tOut))
+       * 
+ * + * uint32 fee = 3; + * @param value The fee to set. + * @return This builder for chaining. + */ + public Builder setFee(int value) { + + fee_ = value; + onChanged(); + return this; + } + /** + *
+       * The transaction fee: present if server can provide. In the case of a
+       * stateless server and a transaction with transparent inputs, this will be
+       * unset because the calculation requires reference to prior transactions.
+       * in a pure-Sapling context, the fee will be calculable as:
+       *    valueBalance + (sum(vPubNew) - sum(vPubOld) - sum(tOut))
+       * 
+ * + * uint32 fee = 3; + * @return This builder for chaining. + */ + public Builder clearFee() { + + fee_ = 0; + onChanged(); + return this; + } + + private java.util.List spends_ = + java.util.Collections.emptyList(); + private void ensureSpendsIsMutable() { + if (!((bitField0_ & 0x00000001) != 0)) { + spends_ = new java.util.ArrayList(spends_); + bitField0_ |= 0x00000001; + } + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend, cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend.Builder, cash.z.wallet.sdk.rpc.CompactFormats.CompactSpendOrBuilder> spendsBuilder_; + + /** + *
+       * inputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + public java.util.List getSpendsList() { + if (spendsBuilder_ == null) { + return java.util.Collections.unmodifiableList(spends_); + } else { + return spendsBuilder_.getMessageList(); + } + } + /** + *
+       * inputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + public int getSpendsCount() { + if (spendsBuilder_ == null) { + return spends_.size(); + } else { + return spendsBuilder_.getCount(); + } + } + /** + *
+       * inputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + public cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend getSpends(int index) { + if (spendsBuilder_ == null) { + return spends_.get(index); + } else { + return spendsBuilder_.getMessage(index); + } + } + /** + *
+       * inputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + public Builder setSpends( + int index, cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend value) { + if (spendsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureSpendsIsMutable(); + spends_.set(index, value); + onChanged(); + } else { + spendsBuilder_.setMessage(index, value); + } + return this; + } + /** + *
+       * inputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + public Builder setSpends( + int index, cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend.Builder builderForValue) { + if (spendsBuilder_ == null) { + ensureSpendsIsMutable(); + spends_.set(index, builderForValue.build()); + onChanged(); + } else { + spendsBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + *
+       * inputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + public Builder addSpends(cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend value) { + if (spendsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureSpendsIsMutable(); + spends_.add(value); + onChanged(); + } else { + spendsBuilder_.addMessage(value); + } + return this; + } + /** + *
+       * inputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + public Builder addSpends( + int index, cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend value) { + if (spendsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureSpendsIsMutable(); + spends_.add(index, value); + onChanged(); + } else { + spendsBuilder_.addMessage(index, value); + } + return this; + } + /** + *
+       * inputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + public Builder addSpends( + cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend.Builder builderForValue) { + if (spendsBuilder_ == null) { + ensureSpendsIsMutable(); + spends_.add(builderForValue.build()); + onChanged(); + } else { + spendsBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + *
+       * inputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + public Builder addSpends( + int index, cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend.Builder builderForValue) { + if (spendsBuilder_ == null) { + ensureSpendsIsMutable(); + spends_.add(index, builderForValue.build()); + onChanged(); + } else { + spendsBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + *
+       * inputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + public Builder addAllSpends( + java.lang.Iterable values) { + if (spendsBuilder_ == null) { + ensureSpendsIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, spends_); + onChanged(); + } else { + spendsBuilder_.addAllMessages(values); + } + return this; + } + /** + *
+       * inputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + public Builder clearSpends() { + if (spendsBuilder_ == null) { + spends_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + } else { + spendsBuilder_.clear(); + } + return this; + } + /** + *
+       * inputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + public Builder removeSpends(int index) { + if (spendsBuilder_ == null) { + ensureSpendsIsMutable(); + spends_.remove(index); + onChanged(); + } else { + spendsBuilder_.remove(index); + } + return this; + } + /** + *
+       * inputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + public cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend.Builder getSpendsBuilder( + int index) { + return getSpendsFieldBuilder().getBuilder(index); + } + /** + *
+       * inputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + public cash.z.wallet.sdk.rpc.CompactFormats.CompactSpendOrBuilder getSpendsOrBuilder( + int index) { + if (spendsBuilder_ == null) { + return spends_.get(index); } else { + return spendsBuilder_.getMessageOrBuilder(index); + } + } + /** + *
+       * inputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + public java.util.List + getSpendsOrBuilderList() { + if (spendsBuilder_ != null) { + return spendsBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(spends_); + } + } + /** + *
+       * inputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + public cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend.Builder addSpendsBuilder() { + return getSpendsFieldBuilder().addBuilder( + cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend.getDefaultInstance()); + } + /** + *
+       * inputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + public cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend.Builder addSpendsBuilder( + int index) { + return getSpendsFieldBuilder().addBuilder( + index, cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend.getDefaultInstance()); + } + /** + *
+       * inputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactSpend spends = 4; + */ + public java.util.List + getSpendsBuilderList() { + return getSpendsFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilderV3< + cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend, cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend.Builder, cash.z.wallet.sdk.rpc.CompactFormats.CompactSpendOrBuilder> + getSpendsFieldBuilder() { + if (spendsBuilder_ == null) { + spendsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3< + cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend, cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend.Builder, cash.z.wallet.sdk.rpc.CompactFormats.CompactSpendOrBuilder>( + spends_, + ((bitField0_ & 0x00000001) != 0), + getParentForChildren(), + isClean()); + spends_ = null; + } + return spendsBuilder_; + } + + private java.util.List outputs_ = + java.util.Collections.emptyList(); + private void ensureOutputsIsMutable() { + if (!((bitField0_ & 0x00000002) != 0)) { + outputs_ = new java.util.ArrayList(outputs_); + bitField0_ |= 0x00000002; + } + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput, cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput.Builder, cash.z.wallet.sdk.rpc.CompactFormats.CompactOutputOrBuilder> outputsBuilder_; + + /** + *
+       * outputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + public java.util.List getOutputsList() { + if (outputsBuilder_ == null) { + return java.util.Collections.unmodifiableList(outputs_); + } else { + return outputsBuilder_.getMessageList(); + } + } + /** + *
+       * outputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + public int getOutputsCount() { + if (outputsBuilder_ == null) { + return outputs_.size(); + } else { + return outputsBuilder_.getCount(); + } + } + /** + *
+       * outputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + public cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput getOutputs(int index) { + if (outputsBuilder_ == null) { + return outputs_.get(index); + } else { + return outputsBuilder_.getMessage(index); + } + } + /** + *
+       * outputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + public Builder setOutputs( + int index, cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput value) { + if (outputsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureOutputsIsMutable(); + outputs_.set(index, value); + onChanged(); + } else { + outputsBuilder_.setMessage(index, value); + } + return this; + } + /** + *
+       * outputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + public Builder setOutputs( + int index, cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput.Builder builderForValue) { + if (outputsBuilder_ == null) { + ensureOutputsIsMutable(); + outputs_.set(index, builderForValue.build()); + onChanged(); + } else { + outputsBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + *
+       * outputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + public Builder addOutputs(cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput value) { + if (outputsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureOutputsIsMutable(); + outputs_.add(value); + onChanged(); + } else { + outputsBuilder_.addMessage(value); + } + return this; + } + /** + *
+       * outputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + public Builder addOutputs( + int index, cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput value) { + if (outputsBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureOutputsIsMutable(); + outputs_.add(index, value); + onChanged(); + } else { + outputsBuilder_.addMessage(index, value); + } + return this; + } + /** + *
+       * outputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + public Builder addOutputs( + cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput.Builder builderForValue) { + if (outputsBuilder_ == null) { + ensureOutputsIsMutable(); + outputs_.add(builderForValue.build()); + onChanged(); + } else { + outputsBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + *
+       * outputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + public Builder addOutputs( + int index, cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput.Builder builderForValue) { + if (outputsBuilder_ == null) { + ensureOutputsIsMutable(); + outputs_.add(index, builderForValue.build()); + onChanged(); + } else { + outputsBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + *
+       * outputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + public Builder addAllOutputs( + java.lang.Iterable values) { + if (outputsBuilder_ == null) { + ensureOutputsIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, outputs_); + onChanged(); + } else { + outputsBuilder_.addAllMessages(values); + } + return this; + } + /** + *
+       * outputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + public Builder clearOutputs() { + if (outputsBuilder_ == null) { + outputs_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + onChanged(); + } else { + outputsBuilder_.clear(); + } + return this; + } + /** + *
+       * outputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + public Builder removeOutputs(int index) { + if (outputsBuilder_ == null) { + ensureOutputsIsMutable(); + outputs_.remove(index); + onChanged(); + } else { + outputsBuilder_.remove(index); + } + return this; + } + /** + *
+       * outputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + public cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput.Builder getOutputsBuilder( + int index) { + return getOutputsFieldBuilder().getBuilder(index); + } + /** + *
+       * outputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + public cash.z.wallet.sdk.rpc.CompactFormats.CompactOutputOrBuilder getOutputsOrBuilder( + int index) { + if (outputsBuilder_ == null) { + return outputs_.get(index); } else { + return outputsBuilder_.getMessageOrBuilder(index); + } + } + /** + *
+       * outputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + public java.util.List + getOutputsOrBuilderList() { + if (outputsBuilder_ != null) { + return outputsBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(outputs_); + } + } + /** + *
+       * outputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + public cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput.Builder addOutputsBuilder() { + return getOutputsFieldBuilder().addBuilder( + cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput.getDefaultInstance()); + } + /** + *
+       * outputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + public cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput.Builder addOutputsBuilder( + int index) { + return getOutputsFieldBuilder().addBuilder( + index, cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput.getDefaultInstance()); + } + /** + *
+       * outputs
+       * 
+ * + * repeated .cash.z.wallet.sdk.rpc.CompactOutput outputs = 5; + */ + public java.util.List + getOutputsBuilderList() { + return getOutputsFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilderV3< + cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput, cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput.Builder, cash.z.wallet.sdk.rpc.CompactFormats.CompactOutputOrBuilder> + getOutputsFieldBuilder() { + if (outputsBuilder_ == null) { + outputsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3< + cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput, cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput.Builder, cash.z.wallet.sdk.rpc.CompactFormats.CompactOutputOrBuilder>( + outputs_, + ((bitField0_ & 0x00000002) != 0), + getParentForChildren(), + isClean()); + outputs_ = null; + } + return outputsBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.CompactTx) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.CompactTx) + private static final cash.z.wallet.sdk.rpc.CompactFormats.CompactTx DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.CompactFormats.CompactTx(); + } + + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactTx getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public CompactTx parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new CompactTx(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.CompactFormats.CompactTx getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface CompactSpendOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.CompactSpend) + com.google.protobuf.MessageOrBuilder { + + /** + *
+     * nullifier (see the Zcash protocol specification)
+     * 
+ * + * bytes nf = 1; + * @return The nf. + */ + com.google.protobuf.ByteString getNf(); + } + /** + *
+   * CompactSpend is a Sapling Spend Description as described in 7.3 of the Zcash
+   * protocol specification.
+   * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.CompactSpend} + */ + public static final class CompactSpend extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.CompactSpend) + CompactSpendOrBuilder { + private static final long serialVersionUID = 0L; + // Use CompactSpend.newBuilder() to construct. + private CompactSpend(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private CompactSpend() { + nf_ = com.google.protobuf.ByteString.EMPTY; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new CompactSpend(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private CompactSpend( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + + nf_ = input.readBytes(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.CompactFormats.internal_static_cash_z_wallet_sdk_rpc_CompactSpend_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.CompactFormats.internal_static_cash_z_wallet_sdk_rpc_CompactSpend_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend.class, cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend.Builder.class); + } + + public static final int NF_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString nf_; + /** + *
+     * nullifier (see the Zcash protocol specification)
+     * 
+ * + * bytes nf = 1; + * @return The nf. + */ + @java.lang.Override + public com.google.protobuf.ByteString getNf() { + return nf_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!nf_.isEmpty()) { + output.writeBytes(1, nf_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!nf_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, nf_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend other = (cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend) obj; + + if (!getNf() + .equals(other.getNf())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + NF_FIELD_NUMBER; + hash = (53 * hash) + getNf().hashCode(); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * CompactSpend is a Sapling Spend Description as described in 7.3 of the Zcash
+     * protocol specification.
+     * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.CompactSpend} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.CompactSpend) + cash.z.wallet.sdk.rpc.CompactFormats.CompactSpendOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.CompactFormats.internal_static_cash_z_wallet_sdk_rpc_CompactSpend_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.CompactFormats.internal_static_cash_z_wallet_sdk_rpc_CompactSpend_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend.class, cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + nf_ = com.google.protobuf.ByteString.EMPTY; + + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.CompactFormats.internal_static_cash_z_wallet_sdk_rpc_CompactSpend_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend build() { + cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend buildPartial() { + cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend result = new cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend(this); + result.nf_ = nf_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend) { + return mergeFrom((cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend other) { + if (other == cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend.getDefaultInstance()) return this; + if (other.getNf() != com.google.protobuf.ByteString.EMPTY) { + setNf(other.getNf()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private com.google.protobuf.ByteString nf_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+       * nullifier (see the Zcash protocol specification)
+       * 
+ * + * bytes nf = 1; + * @return The nf. + */ + @java.lang.Override + public com.google.protobuf.ByteString getNf() { + return nf_; + } + /** + *
+       * nullifier (see the Zcash protocol specification)
+       * 
+ * + * bytes nf = 1; + * @param value The nf to set. + * @return This builder for chaining. + */ + public Builder setNf(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + + nf_ = value; + onChanged(); + return this; + } + /** + *
+       * nullifier (see the Zcash protocol specification)
+       * 
+ * + * bytes nf = 1; + * @return This builder for chaining. + */ + public Builder clearNf() { + + nf_ = getDefaultInstance().getNf(); + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.CompactSpend) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.CompactSpend) + private static final cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend(); + } + + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public CompactSpend parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new CompactSpend(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.CompactFormats.CompactSpend getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface CompactOutputOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.CompactOutput) + com.google.protobuf.MessageOrBuilder { + + /** + *
+     * note commitment u-coordinate
+     * 
+ * + * bytes cmu = 1; + * @return The cmu. + */ + com.google.protobuf.ByteString getCmu(); + + /** + *
+     * ephemeral public key
+     * 
+ * + * bytes epk = 2; + * @return The epk. + */ + com.google.protobuf.ByteString getEpk(); + + /** + *
+     * ciphertext and zkproof
+     * 
+ * + * bytes ciphertext = 3; + * @return The ciphertext. + */ + com.google.protobuf.ByteString getCiphertext(); + } + /** + *
+   * output is a Sapling Output Description as described in section 7.4 of the
+   * Zcash protocol spec. Total size is 948.
+   * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.CompactOutput} + */ + public static final class CompactOutput extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.CompactOutput) + CompactOutputOrBuilder { + private static final long serialVersionUID = 0L; + // Use CompactOutput.newBuilder() to construct. + private CompactOutput(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private CompactOutput() { + cmu_ = com.google.protobuf.ByteString.EMPTY; + epk_ = com.google.protobuf.ByteString.EMPTY; + ciphertext_ = com.google.protobuf.ByteString.EMPTY; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new CompactOutput(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private CompactOutput( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + + cmu_ = input.readBytes(); + break; + } + case 18: { + + epk_ = input.readBytes(); + break; + } + case 26: { + + ciphertext_ = input.readBytes(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.CompactFormats.internal_static_cash_z_wallet_sdk_rpc_CompactOutput_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.CompactFormats.internal_static_cash_z_wallet_sdk_rpc_CompactOutput_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput.class, cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput.Builder.class); + } + + public static final int CMU_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString cmu_; + /** + *
+     * note commitment u-coordinate
+     * 
+ * + * bytes cmu = 1; + * @return The cmu. + */ + @java.lang.Override + public com.google.protobuf.ByteString getCmu() { + return cmu_; + } + + public static final int EPK_FIELD_NUMBER = 2; + private com.google.protobuf.ByteString epk_; + /** + *
+     * ephemeral public key
+     * 
+ * + * bytes epk = 2; + * @return The epk. + */ + @java.lang.Override + public com.google.protobuf.ByteString getEpk() { + return epk_; + } + + public static final int CIPHERTEXT_FIELD_NUMBER = 3; + private com.google.protobuf.ByteString ciphertext_; + /** + *
+     * ciphertext and zkproof
+     * 
+ * + * bytes ciphertext = 3; + * @return The ciphertext. + */ + @java.lang.Override + public com.google.protobuf.ByteString getCiphertext() { + return ciphertext_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!cmu_.isEmpty()) { + output.writeBytes(1, cmu_); + } + if (!epk_.isEmpty()) { + output.writeBytes(2, epk_); + } + if (!ciphertext_.isEmpty()) { + output.writeBytes(3, ciphertext_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!cmu_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, cmu_); + } + if (!epk_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, epk_); + } + if (!ciphertext_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, ciphertext_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput other = (cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput) obj; + + if (!getCmu() + .equals(other.getCmu())) return false; + if (!getEpk() + .equals(other.getEpk())) return false; + if (!getCiphertext() + .equals(other.getCiphertext())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + CMU_FIELD_NUMBER; + hash = (53 * hash) + getCmu().hashCode(); + hash = (37 * hash) + EPK_FIELD_NUMBER; + hash = (53 * hash) + getEpk().hashCode(); + hash = (37 * hash) + CIPHERTEXT_FIELD_NUMBER; + hash = (53 * hash) + getCiphertext().hashCode(); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * output is a Sapling Output Description as described in section 7.4 of the
+     * Zcash protocol spec. Total size is 948.
+     * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.CompactOutput} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.CompactOutput) + cash.z.wallet.sdk.rpc.CompactFormats.CompactOutputOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.CompactFormats.internal_static_cash_z_wallet_sdk_rpc_CompactOutput_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.CompactFormats.internal_static_cash_z_wallet_sdk_rpc_CompactOutput_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput.class, cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + cmu_ = com.google.protobuf.ByteString.EMPTY; + + epk_ = com.google.protobuf.ByteString.EMPTY; + + ciphertext_ = com.google.protobuf.ByteString.EMPTY; + + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.CompactFormats.internal_static_cash_z_wallet_sdk_rpc_CompactOutput_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput build() { + cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput buildPartial() { + cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput result = new cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput(this); + result.cmu_ = cmu_; + result.epk_ = epk_; + result.ciphertext_ = ciphertext_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput) { + return mergeFrom((cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput other) { + if (other == cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput.getDefaultInstance()) return this; + if (other.getCmu() != com.google.protobuf.ByteString.EMPTY) { + setCmu(other.getCmu()); + } + if (other.getEpk() != com.google.protobuf.ByteString.EMPTY) { + setEpk(other.getEpk()); + } + if (other.getCiphertext() != com.google.protobuf.ByteString.EMPTY) { + setCiphertext(other.getCiphertext()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private com.google.protobuf.ByteString cmu_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+       * note commitment u-coordinate
+       * 
+ * + * bytes cmu = 1; + * @return The cmu. + */ + @java.lang.Override + public com.google.protobuf.ByteString getCmu() { + return cmu_; + } + /** + *
+       * note commitment u-coordinate
+       * 
+ * + * bytes cmu = 1; + * @param value The cmu to set. + * @return This builder for chaining. + */ + public Builder setCmu(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + + cmu_ = value; + onChanged(); + return this; + } + /** + *
+       * note commitment u-coordinate
+       * 
+ * + * bytes cmu = 1; + * @return This builder for chaining. + */ + public Builder clearCmu() { + + cmu_ = getDefaultInstance().getCmu(); + onChanged(); + return this; + } + + private com.google.protobuf.ByteString epk_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+       * ephemeral public key
+       * 
+ * + * bytes epk = 2; + * @return The epk. + */ + @java.lang.Override + public com.google.protobuf.ByteString getEpk() { + return epk_; + } + /** + *
+       * ephemeral public key
+       * 
+ * + * bytes epk = 2; + * @param value The epk to set. + * @return This builder for chaining. + */ + public Builder setEpk(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + + epk_ = value; + onChanged(); + return this; + } + /** + *
+       * ephemeral public key
+       * 
+ * + * bytes epk = 2; + * @return This builder for chaining. + */ + public Builder clearEpk() { + + epk_ = getDefaultInstance().getEpk(); + onChanged(); + return this; + } + + private com.google.protobuf.ByteString ciphertext_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+       * ciphertext and zkproof
+       * 
+ * + * bytes ciphertext = 3; + * @return The ciphertext. + */ + @java.lang.Override + public com.google.protobuf.ByteString getCiphertext() { + return ciphertext_; + } + /** + *
+       * ciphertext and zkproof
+       * 
+ * + * bytes ciphertext = 3; + * @param value The ciphertext to set. + * @return This builder for chaining. + */ + public Builder setCiphertext(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + + ciphertext_ = value; + onChanged(); + return this; + } + /** + *
+       * ciphertext and zkproof
+       * 
+ * + * bytes ciphertext = 3; + * @return This builder for chaining. + */ + public Builder clearCiphertext() { + + ciphertext_ = getDefaultInstance().getCiphertext(); + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.CompactOutput) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.CompactOutput) + private static final cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput(); + } + + public static cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public CompactOutput parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new CompactOutput(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.CompactFormats.CompactOutput getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_CompactBlock_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_CompactBlock_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_CompactTx_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_CompactTx_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_CompactSpend_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_CompactSpend_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_CompactOutput_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_CompactOutput_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + java.lang.String[] descriptorData = { + "\n\025compact_formats.proto\022\025cash.z.wallet.s" + + "dk.rpc\"\241\001\n\014CompactBlock\022\024\n\014protoVersion\030" + + "\001 \001(\r\022\016\n\006height\030\002 \001(\004\022\014\n\004hash\030\003 \001(\014\022\020\n\010p" + + "revHash\030\004 \001(\014\022\014\n\004time\030\005 \001(\r\022\016\n\006header\030\006 " + + "\001(\014\022-\n\003vtx\030\007 \003(\0132 .cash.z.wallet.sdk.rpc" + + ".CompactTx\"\241\001\n\tCompactTx\022\r\n\005index\030\001 \001(\004\022" + + "\014\n\004hash\030\002 \001(\014\022\013\n\003fee\030\003 \001(\r\0223\n\006spends\030\004 \003" + + "(\0132#.cash.z.wallet.sdk.rpc.CompactSpend\022" + + "5\n\007outputs\030\005 \003(\0132$.cash.z.wallet.sdk.rpc" + + ".CompactOutput\"\032\n\014CompactSpend\022\n\n\002nf\030\001 \001" + + "(\014\"=\n\rCompactOutput\022\013\n\003cmu\030\001 \001(\014\022\013\n\003epk\030" + + "\002 \001(\014\022\022\n\nciphertext\030\003 \001(\014B\033Z\026lightwallet" + + "d/walletrpc\272\002\000b\006proto3" + }; + descriptor = com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + }); + internal_static_cash_z_wallet_sdk_rpc_CompactBlock_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_cash_z_wallet_sdk_rpc_CompactBlock_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_CompactBlock_descriptor, + new java.lang.String[] { "ProtoVersion", "Height", "Hash", "PrevHash", "Time", "Header", "Vtx", }); + internal_static_cash_z_wallet_sdk_rpc_CompactTx_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_cash_z_wallet_sdk_rpc_CompactTx_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_CompactTx_descriptor, + new java.lang.String[] { "Index", "Hash", "Fee", "Spends", "Outputs", }); + internal_static_cash_z_wallet_sdk_rpc_CompactSpend_descriptor = + getDescriptor().getMessageTypes().get(2); + internal_static_cash_z_wallet_sdk_rpc_CompactSpend_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_CompactSpend_descriptor, + new java.lang.String[] { "Nf", }); + internal_static_cash_z_wallet_sdk_rpc_CompactOutput_descriptor = + getDescriptor().getMessageTypes().get(3); + internal_static_cash_z_wallet_sdk_rpc_CompactOutput_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_CompactOutput_descriptor, + new java.lang.String[] { "Cmu", "Epk", "Ciphertext", }); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/src/main/java/cash/z/wallet/sdk/rpc/CompactTxStreamerGrpc.java b/src/main/java/cash/z/wallet/sdk/rpc/CompactTxStreamerGrpc.java new file mode 100644 index 00000000..53b64c05 --- /dev/null +++ b/src/main/java/cash/z/wallet/sdk/rpc/CompactTxStreamerGrpc.java @@ -0,0 +1,1341 @@ +package cash.z.wallet.sdk.rpc; + +import static io.grpc.MethodDescriptor.generateFullMethodName; + +/** + */ +@javax.annotation.Generated( + value = "by gRPC proto compiler (version 1.45.1)", + comments = "Source: service.proto") +@io.grpc.stub.annotations.GrpcGenerated +public final class CompactTxStreamerGrpc { + + private CompactTxStreamerGrpc() {} + + public static final String SERVICE_NAME = "cash.z.wallet.sdk.rpc.CompactTxStreamer"; + + // Static method descriptors that strictly reflect the proto. + private static volatile io.grpc.MethodDescriptor getGetLatestBlockMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "GetLatestBlock", + requestType = cash.z.wallet.sdk.rpc.Service.ChainSpec.class, + responseType = cash.z.wallet.sdk.rpc.Service.BlockID.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getGetLatestBlockMethod() { + io.grpc.MethodDescriptor getGetLatestBlockMethod; + if ((getGetLatestBlockMethod = CompactTxStreamerGrpc.getGetLatestBlockMethod) == null) { + synchronized (CompactTxStreamerGrpc.class) { + if ((getGetLatestBlockMethod = CompactTxStreamerGrpc.getGetLatestBlockMethod) == null) { + CompactTxStreamerGrpc.getGetLatestBlockMethod = getGetLatestBlockMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetLatestBlock")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.ChainSpec.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.BlockID.getDefaultInstance())) + .setSchemaDescriptor(new CompactTxStreamerMethodDescriptorSupplier("GetLatestBlock")) + .build(); + } + } + } + return getGetLatestBlockMethod; + } + + private static volatile io.grpc.MethodDescriptor getGetBlockMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "GetBlock", + requestType = cash.z.wallet.sdk.rpc.Service.BlockID.class, + responseType = cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getGetBlockMethod() { + io.grpc.MethodDescriptor getGetBlockMethod; + if ((getGetBlockMethod = CompactTxStreamerGrpc.getGetBlockMethod) == null) { + synchronized (CompactTxStreamerGrpc.class) { + if ((getGetBlockMethod = CompactTxStreamerGrpc.getGetBlockMethod) == null) { + CompactTxStreamerGrpc.getGetBlockMethod = getGetBlockMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetBlock")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.BlockID.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock.getDefaultInstance())) + .setSchemaDescriptor(new CompactTxStreamerMethodDescriptorSupplier("GetBlock")) + .build(); + } + } + } + return getGetBlockMethod; + } + + private static volatile io.grpc.MethodDescriptor getGetBlockRangeMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "GetBlockRange", + requestType = cash.z.wallet.sdk.rpc.Service.BlockRange.class, + responseType = cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock.class, + methodType = io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING) + public static io.grpc.MethodDescriptor getGetBlockRangeMethod() { + io.grpc.MethodDescriptor getGetBlockRangeMethod; + if ((getGetBlockRangeMethod = CompactTxStreamerGrpc.getGetBlockRangeMethod) == null) { + synchronized (CompactTxStreamerGrpc.class) { + if ((getGetBlockRangeMethod = CompactTxStreamerGrpc.getGetBlockRangeMethod) == null) { + CompactTxStreamerGrpc.getGetBlockRangeMethod = getGetBlockRangeMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetBlockRange")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.BlockRange.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock.getDefaultInstance())) + .setSchemaDescriptor(new CompactTxStreamerMethodDescriptorSupplier("GetBlockRange")) + .build(); + } + } + } + return getGetBlockRangeMethod; + } + + private static volatile io.grpc.MethodDescriptor getGetTransactionMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "GetTransaction", + requestType = cash.z.wallet.sdk.rpc.Service.TxFilter.class, + responseType = cash.z.wallet.sdk.rpc.Service.RawTransaction.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getGetTransactionMethod() { + io.grpc.MethodDescriptor getGetTransactionMethod; + if ((getGetTransactionMethod = CompactTxStreamerGrpc.getGetTransactionMethod) == null) { + synchronized (CompactTxStreamerGrpc.class) { + if ((getGetTransactionMethod = CompactTxStreamerGrpc.getGetTransactionMethod) == null) { + CompactTxStreamerGrpc.getGetTransactionMethod = getGetTransactionMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetTransaction")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.TxFilter.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.RawTransaction.getDefaultInstance())) + .setSchemaDescriptor(new CompactTxStreamerMethodDescriptorSupplier("GetTransaction")) + .build(); + } + } + } + return getGetTransactionMethod; + } + + private static volatile io.grpc.MethodDescriptor getSendTransactionMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "SendTransaction", + requestType = cash.z.wallet.sdk.rpc.Service.RawTransaction.class, + responseType = cash.z.wallet.sdk.rpc.Service.SendResponse.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getSendTransactionMethod() { + io.grpc.MethodDescriptor getSendTransactionMethod; + if ((getSendTransactionMethod = CompactTxStreamerGrpc.getSendTransactionMethod) == null) { + synchronized (CompactTxStreamerGrpc.class) { + if ((getSendTransactionMethod = CompactTxStreamerGrpc.getSendTransactionMethod) == null) { + CompactTxStreamerGrpc.getSendTransactionMethod = getSendTransactionMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "SendTransaction")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.RawTransaction.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.SendResponse.getDefaultInstance())) + .setSchemaDescriptor(new CompactTxStreamerMethodDescriptorSupplier("SendTransaction")) + .build(); + } + } + } + return getSendTransactionMethod; + } + + private static volatile io.grpc.MethodDescriptor getGetTaddressTxidsMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "GetTaddressTxids", + requestType = cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter.class, + responseType = cash.z.wallet.sdk.rpc.Service.RawTransaction.class, + methodType = io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING) + public static io.grpc.MethodDescriptor getGetTaddressTxidsMethod() { + io.grpc.MethodDescriptor getGetTaddressTxidsMethod; + if ((getGetTaddressTxidsMethod = CompactTxStreamerGrpc.getGetTaddressTxidsMethod) == null) { + synchronized (CompactTxStreamerGrpc.class) { + if ((getGetTaddressTxidsMethod = CompactTxStreamerGrpc.getGetTaddressTxidsMethod) == null) { + CompactTxStreamerGrpc.getGetTaddressTxidsMethod = getGetTaddressTxidsMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetTaddressTxids")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.RawTransaction.getDefaultInstance())) + .setSchemaDescriptor(new CompactTxStreamerMethodDescriptorSupplier("GetTaddressTxids")) + .build(); + } + } + } + return getGetTaddressTxidsMethod; + } + + private static volatile io.grpc.MethodDescriptor getGetTaddressBalanceMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "GetTaddressBalance", + requestType = cash.z.wallet.sdk.rpc.Service.AddressList.class, + responseType = cash.z.wallet.sdk.rpc.Service.Balance.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getGetTaddressBalanceMethod() { + io.grpc.MethodDescriptor getGetTaddressBalanceMethod; + if ((getGetTaddressBalanceMethod = CompactTxStreamerGrpc.getGetTaddressBalanceMethod) == null) { + synchronized (CompactTxStreamerGrpc.class) { + if ((getGetTaddressBalanceMethod = CompactTxStreamerGrpc.getGetTaddressBalanceMethod) == null) { + CompactTxStreamerGrpc.getGetTaddressBalanceMethod = getGetTaddressBalanceMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetTaddressBalance")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.AddressList.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.Balance.getDefaultInstance())) + .setSchemaDescriptor(new CompactTxStreamerMethodDescriptorSupplier("GetTaddressBalance")) + .build(); + } + } + } + return getGetTaddressBalanceMethod; + } + + private static volatile io.grpc.MethodDescriptor getGetTaddressBalanceStreamMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "GetTaddressBalanceStream", + requestType = cash.z.wallet.sdk.rpc.Service.Address.class, + responseType = cash.z.wallet.sdk.rpc.Service.Balance.class, + methodType = io.grpc.MethodDescriptor.MethodType.CLIENT_STREAMING) + public static io.grpc.MethodDescriptor getGetTaddressBalanceStreamMethod() { + io.grpc.MethodDescriptor getGetTaddressBalanceStreamMethod; + if ((getGetTaddressBalanceStreamMethod = CompactTxStreamerGrpc.getGetTaddressBalanceStreamMethod) == null) { + synchronized (CompactTxStreamerGrpc.class) { + if ((getGetTaddressBalanceStreamMethod = CompactTxStreamerGrpc.getGetTaddressBalanceStreamMethod) == null) { + CompactTxStreamerGrpc.getGetTaddressBalanceStreamMethod = getGetTaddressBalanceStreamMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.CLIENT_STREAMING) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetTaddressBalanceStream")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.Address.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.Balance.getDefaultInstance())) + .setSchemaDescriptor(new CompactTxStreamerMethodDescriptorSupplier("GetTaddressBalanceStream")) + .build(); + } + } + } + return getGetTaddressBalanceStreamMethod; + } + + private static volatile io.grpc.MethodDescriptor getGetMempoolTxMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "GetMempoolTx", + requestType = cash.z.wallet.sdk.rpc.Service.Exclude.class, + responseType = cash.z.wallet.sdk.rpc.CompactFormats.CompactTx.class, + methodType = io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING) + public static io.grpc.MethodDescriptor getGetMempoolTxMethod() { + io.grpc.MethodDescriptor getGetMempoolTxMethod; + if ((getGetMempoolTxMethod = CompactTxStreamerGrpc.getGetMempoolTxMethod) == null) { + synchronized (CompactTxStreamerGrpc.class) { + if ((getGetMempoolTxMethod = CompactTxStreamerGrpc.getGetMempoolTxMethod) == null) { + CompactTxStreamerGrpc.getGetMempoolTxMethod = getGetMempoolTxMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetMempoolTx")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.Exclude.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.CompactFormats.CompactTx.getDefaultInstance())) + .setSchemaDescriptor(new CompactTxStreamerMethodDescriptorSupplier("GetMempoolTx")) + .build(); + } + } + } + return getGetMempoolTxMethod; + } + + private static volatile io.grpc.MethodDescriptor getGetTreeStateMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "GetTreeState", + requestType = cash.z.wallet.sdk.rpc.Service.BlockID.class, + responseType = cash.z.wallet.sdk.rpc.Service.TreeState.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getGetTreeStateMethod() { + io.grpc.MethodDescriptor getGetTreeStateMethod; + if ((getGetTreeStateMethod = CompactTxStreamerGrpc.getGetTreeStateMethod) == null) { + synchronized (CompactTxStreamerGrpc.class) { + if ((getGetTreeStateMethod = CompactTxStreamerGrpc.getGetTreeStateMethod) == null) { + CompactTxStreamerGrpc.getGetTreeStateMethod = getGetTreeStateMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetTreeState")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.BlockID.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.TreeState.getDefaultInstance())) + .setSchemaDescriptor(new CompactTxStreamerMethodDescriptorSupplier("GetTreeState")) + .build(); + } + } + } + return getGetTreeStateMethod; + } + + private static volatile io.grpc.MethodDescriptor getGetAddressUtxosMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "GetAddressUtxos", + requestType = cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg.class, + responseType = cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getGetAddressUtxosMethod() { + io.grpc.MethodDescriptor getGetAddressUtxosMethod; + if ((getGetAddressUtxosMethod = CompactTxStreamerGrpc.getGetAddressUtxosMethod) == null) { + synchronized (CompactTxStreamerGrpc.class) { + if ((getGetAddressUtxosMethod = CompactTxStreamerGrpc.getGetAddressUtxosMethod) == null) { + CompactTxStreamerGrpc.getGetAddressUtxosMethod = getGetAddressUtxosMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetAddressUtxos")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList.getDefaultInstance())) + .setSchemaDescriptor(new CompactTxStreamerMethodDescriptorSupplier("GetAddressUtxos")) + .build(); + } + } + } + return getGetAddressUtxosMethod; + } + + private static volatile io.grpc.MethodDescriptor getGetAddressUtxosStreamMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "GetAddressUtxosStream", + requestType = cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg.class, + responseType = cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply.class, + methodType = io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING) + public static io.grpc.MethodDescriptor getGetAddressUtxosStreamMethod() { + io.grpc.MethodDescriptor getGetAddressUtxosStreamMethod; + if ((getGetAddressUtxosStreamMethod = CompactTxStreamerGrpc.getGetAddressUtxosStreamMethod) == null) { + synchronized (CompactTxStreamerGrpc.class) { + if ((getGetAddressUtxosStreamMethod = CompactTxStreamerGrpc.getGetAddressUtxosStreamMethod) == null) { + CompactTxStreamerGrpc.getGetAddressUtxosStreamMethod = getGetAddressUtxosStreamMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetAddressUtxosStream")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply.getDefaultInstance())) + .setSchemaDescriptor(new CompactTxStreamerMethodDescriptorSupplier("GetAddressUtxosStream")) + .build(); + } + } + } + return getGetAddressUtxosStreamMethod; + } + + private static volatile io.grpc.MethodDescriptor getGetLightdInfoMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "GetLightdInfo", + requestType = cash.z.wallet.sdk.rpc.Service.Empty.class, + responseType = cash.z.wallet.sdk.rpc.Service.LightdInfo.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getGetLightdInfoMethod() { + io.grpc.MethodDescriptor getGetLightdInfoMethod; + if ((getGetLightdInfoMethod = CompactTxStreamerGrpc.getGetLightdInfoMethod) == null) { + synchronized (CompactTxStreamerGrpc.class) { + if ((getGetLightdInfoMethod = CompactTxStreamerGrpc.getGetLightdInfoMethod) == null) { + CompactTxStreamerGrpc.getGetLightdInfoMethod = getGetLightdInfoMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetLightdInfo")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.Empty.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.LightdInfo.getDefaultInstance())) + .setSchemaDescriptor(new CompactTxStreamerMethodDescriptorSupplier("GetLightdInfo")) + .build(); + } + } + } + return getGetLightdInfoMethod; + } + + private static volatile io.grpc.MethodDescriptor getPingMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "Ping", + requestType = cash.z.wallet.sdk.rpc.Service.Duration.class, + responseType = cash.z.wallet.sdk.rpc.Service.PingResponse.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getPingMethod() { + io.grpc.MethodDescriptor getPingMethod; + if ((getPingMethod = CompactTxStreamerGrpc.getPingMethod) == null) { + synchronized (CompactTxStreamerGrpc.class) { + if ((getPingMethod = CompactTxStreamerGrpc.getPingMethod) == null) { + CompactTxStreamerGrpc.getPingMethod = getPingMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "Ping")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.Duration.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.PingResponse.getDefaultInstance())) + .setSchemaDescriptor(new CompactTxStreamerMethodDescriptorSupplier("Ping")) + .build(); + } + } + } + return getPingMethod; + } + + /** + * Creates a new async stub that supports all call types for the service + */ + public static CompactTxStreamerStub newStub(io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public CompactTxStreamerStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new CompactTxStreamerStub(channel, callOptions); + } + }; + return CompactTxStreamerStub.newStub(factory, channel); + } + + /** + * Creates a new blocking-style stub that supports unary and streaming output calls on the service + */ + public static CompactTxStreamerBlockingStub newBlockingStub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public CompactTxStreamerBlockingStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new CompactTxStreamerBlockingStub(channel, callOptions); + } + }; + return CompactTxStreamerBlockingStub.newStub(factory, channel); + } + + /** + * Creates a new ListenableFuture-style stub that supports unary calls on the service + */ + public static CompactTxStreamerFutureStub newFutureStub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public CompactTxStreamerFutureStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new CompactTxStreamerFutureStub(channel, callOptions); + } + }; + return CompactTxStreamerFutureStub.newStub(factory, channel); + } + + /** + */ + public static abstract class CompactTxStreamerImplBase implements io.grpc.BindableService { + + /** + *
+     * Return the height of the tip of the best chain
+     * 
+ */ + public void getLatestBlock(cash.z.wallet.sdk.rpc.Service.ChainSpec request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetLatestBlockMethod(), responseObserver); + } + + /** + *
+     * Return the compact block corresponding to the given block identifier
+     * 
+ */ + public void getBlock(cash.z.wallet.sdk.rpc.Service.BlockID request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetBlockMethod(), responseObserver); + } + + /** + *
+     * Return a list of consecutive compact blocks
+     * 
+ */ + public void getBlockRange(cash.z.wallet.sdk.rpc.Service.BlockRange request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetBlockRangeMethod(), responseObserver); + } + + /** + *
+     * Return the requested full (not compact) transaction (as from pirated)
+     * 
+ */ + public void getTransaction(cash.z.wallet.sdk.rpc.Service.TxFilter request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetTransactionMethod(), responseObserver); + } + + /** + *
+     * Submit the given transaction to the Zcash network
+     * 
+ */ + public void sendTransaction(cash.z.wallet.sdk.rpc.Service.RawTransaction request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getSendTransactionMethod(), responseObserver); + } + + /** + *
+     * Return the txids corresponding to the given t-address within the given block range
+     * 
+ */ + public void getTaddressTxids(cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetTaddressTxidsMethod(), responseObserver); + } + + /** + */ + public void getTaddressBalance(cash.z.wallet.sdk.rpc.Service.AddressList request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetTaddressBalanceMethod(), responseObserver); + } + + /** + */ + public io.grpc.stub.StreamObserver getTaddressBalanceStream( + io.grpc.stub.StreamObserver responseObserver) { + return io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall(getGetTaddressBalanceStreamMethod(), responseObserver); + } + + /** + *
+     * Return the compact transactions currently in the mempool; the results
+     * can be a few seconds out of date. If the Exclude list is empty, return
+     * all transactions; otherwise return all *except* those in the Exclude list
+     * (if any); this allows the client to avoid receiving transactions that it
+     * already has (from an earlier call to this rpc). The transaction IDs in the
+     * Exclude list can be shortened to any number of bytes to make the request
+     * more bandwidth-efficient; if two or more transactions in the mempool
+     * match a shortened txid, they are all sent (none is excluded). Transactions
+     * in the exclude list that don't exist in the mempool are ignored.
+     * 
+ */ + public void getMempoolTx(cash.z.wallet.sdk.rpc.Service.Exclude request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetMempoolTxMethod(), responseObserver); + } + + /** + *
+     * GetTreeState returns the note commitment tree state corresponding to the given block.
+     * See section 3.7 of the Zcash protocol specification. It returns several other useful
+     * values also (even though they can be obtained using GetBlock).
+     * The block can be specified by either height or hash.
+     * 
+ */ + public void getTreeState(cash.z.wallet.sdk.rpc.Service.BlockID request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetTreeStateMethod(), responseObserver); + } + + /** + */ + public void getAddressUtxos(cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetAddressUtxosMethod(), responseObserver); + } + + /** + */ + public void getAddressUtxosStream(cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetAddressUtxosStreamMethod(), responseObserver); + } + + /** + *
+     * Return information about this lightwalletd instance and the blockchain
+     * 
+ */ + public void getLightdInfo(cash.z.wallet.sdk.rpc.Service.Empty request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetLightdInfoMethod(), responseObserver); + } + + /** + *
+     * Testing-only, requires lightwalletd --ping-very-insecure (do not enable in production)
+     * 
+ */ + public void ping(cash.z.wallet.sdk.rpc.Service.Duration request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getPingMethod(), responseObserver); + } + + @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + getGetLatestBlockMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + cash.z.wallet.sdk.rpc.Service.ChainSpec, + cash.z.wallet.sdk.rpc.Service.BlockID>( + this, METHODID_GET_LATEST_BLOCK))) + .addMethod( + getGetBlockMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + cash.z.wallet.sdk.rpc.Service.BlockID, + cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock>( + this, METHODID_GET_BLOCK))) + .addMethod( + getGetBlockRangeMethod(), + io.grpc.stub.ServerCalls.asyncServerStreamingCall( + new MethodHandlers< + cash.z.wallet.sdk.rpc.Service.BlockRange, + cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock>( + this, METHODID_GET_BLOCK_RANGE))) + .addMethod( + getGetTransactionMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + cash.z.wallet.sdk.rpc.Service.TxFilter, + cash.z.wallet.sdk.rpc.Service.RawTransaction>( + this, METHODID_GET_TRANSACTION))) + .addMethod( + getSendTransactionMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + cash.z.wallet.sdk.rpc.Service.RawTransaction, + cash.z.wallet.sdk.rpc.Service.SendResponse>( + this, METHODID_SEND_TRANSACTION))) + .addMethod( + getGetTaddressTxidsMethod(), + io.grpc.stub.ServerCalls.asyncServerStreamingCall( + new MethodHandlers< + cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter, + cash.z.wallet.sdk.rpc.Service.RawTransaction>( + this, METHODID_GET_TADDRESS_TXIDS))) + .addMethod( + getGetTaddressBalanceMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + cash.z.wallet.sdk.rpc.Service.AddressList, + cash.z.wallet.sdk.rpc.Service.Balance>( + this, METHODID_GET_TADDRESS_BALANCE))) + .addMethod( + getGetTaddressBalanceStreamMethod(), + io.grpc.stub.ServerCalls.asyncClientStreamingCall( + new MethodHandlers< + cash.z.wallet.sdk.rpc.Service.Address, + cash.z.wallet.sdk.rpc.Service.Balance>( + this, METHODID_GET_TADDRESS_BALANCE_STREAM))) + .addMethod( + getGetMempoolTxMethod(), + io.grpc.stub.ServerCalls.asyncServerStreamingCall( + new MethodHandlers< + cash.z.wallet.sdk.rpc.Service.Exclude, + cash.z.wallet.sdk.rpc.CompactFormats.CompactTx>( + this, METHODID_GET_MEMPOOL_TX))) + .addMethod( + getGetTreeStateMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + cash.z.wallet.sdk.rpc.Service.BlockID, + cash.z.wallet.sdk.rpc.Service.TreeState>( + this, METHODID_GET_TREE_STATE))) + .addMethod( + getGetAddressUtxosMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg, + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList>( + this, METHODID_GET_ADDRESS_UTXOS))) + .addMethod( + getGetAddressUtxosStreamMethod(), + io.grpc.stub.ServerCalls.asyncServerStreamingCall( + new MethodHandlers< + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg, + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply>( + this, METHODID_GET_ADDRESS_UTXOS_STREAM))) + .addMethod( + getGetLightdInfoMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + cash.z.wallet.sdk.rpc.Service.Empty, + cash.z.wallet.sdk.rpc.Service.LightdInfo>( + this, METHODID_GET_LIGHTD_INFO))) + .addMethod( + getPingMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + cash.z.wallet.sdk.rpc.Service.Duration, + cash.z.wallet.sdk.rpc.Service.PingResponse>( + this, METHODID_PING))) + .build(); + } + } + + /** + */ + public static final class CompactTxStreamerStub extends io.grpc.stub.AbstractAsyncStub { + private CompactTxStreamerStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected CompactTxStreamerStub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new CompactTxStreamerStub(channel, callOptions); + } + + /** + *
+     * Return the height of the tip of the best chain
+     * 
+ */ + public void getLatestBlock(cash.z.wallet.sdk.rpc.Service.ChainSpec request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getGetLatestBlockMethod(), getCallOptions()), request, responseObserver); + } + + /** + *
+     * Return the compact block corresponding to the given block identifier
+     * 
+ */ + public void getBlock(cash.z.wallet.sdk.rpc.Service.BlockID request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getGetBlockMethod(), getCallOptions()), request, responseObserver); + } + + /** + *
+     * Return a list of consecutive compact blocks
+     * 
+ */ + public void getBlockRange(cash.z.wallet.sdk.rpc.Service.BlockRange request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncServerStreamingCall( + getChannel().newCall(getGetBlockRangeMethod(), getCallOptions()), request, responseObserver); + } + + /** + *
+     * Return the requested full (not compact) transaction (as from pirated)
+     * 
+ */ + public void getTransaction(cash.z.wallet.sdk.rpc.Service.TxFilter request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getGetTransactionMethod(), getCallOptions()), request, responseObserver); + } + + /** + *
+     * Submit the given transaction to the Zcash network
+     * 
+ */ + public void sendTransaction(cash.z.wallet.sdk.rpc.Service.RawTransaction request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getSendTransactionMethod(), getCallOptions()), request, responseObserver); + } + + /** + *
+     * Return the txids corresponding to the given t-address within the given block range
+     * 
+ */ + public void getTaddressTxids(cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncServerStreamingCall( + getChannel().newCall(getGetTaddressTxidsMethod(), getCallOptions()), request, responseObserver); + } + + /** + */ + public void getTaddressBalance(cash.z.wallet.sdk.rpc.Service.AddressList request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getGetTaddressBalanceMethod(), getCallOptions()), request, responseObserver); + } + + /** + */ + public io.grpc.stub.StreamObserver getTaddressBalanceStream( + io.grpc.stub.StreamObserver responseObserver) { + return io.grpc.stub.ClientCalls.asyncClientStreamingCall( + getChannel().newCall(getGetTaddressBalanceStreamMethod(), getCallOptions()), responseObserver); + } + + /** + *
+     * Return the compact transactions currently in the mempool; the results
+     * can be a few seconds out of date. If the Exclude list is empty, return
+     * all transactions; otherwise return all *except* those in the Exclude list
+     * (if any); this allows the client to avoid receiving transactions that it
+     * already has (from an earlier call to this rpc). The transaction IDs in the
+     * Exclude list can be shortened to any number of bytes to make the request
+     * more bandwidth-efficient; if two or more transactions in the mempool
+     * match a shortened txid, they are all sent (none is excluded). Transactions
+     * in the exclude list that don't exist in the mempool are ignored.
+     * 
+ */ + public void getMempoolTx(cash.z.wallet.sdk.rpc.Service.Exclude request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncServerStreamingCall( + getChannel().newCall(getGetMempoolTxMethod(), getCallOptions()), request, responseObserver); + } + + /** + *
+     * GetTreeState returns the note commitment tree state corresponding to the given block.
+     * See section 3.7 of the Zcash protocol specification. It returns several other useful
+     * values also (even though they can be obtained using GetBlock).
+     * The block can be specified by either height or hash.
+     * 
+ */ + public void getTreeState(cash.z.wallet.sdk.rpc.Service.BlockID request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getGetTreeStateMethod(), getCallOptions()), request, responseObserver); + } + + /** + */ + public void getAddressUtxos(cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getGetAddressUtxosMethod(), getCallOptions()), request, responseObserver); + } + + /** + */ + public void getAddressUtxosStream(cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncServerStreamingCall( + getChannel().newCall(getGetAddressUtxosStreamMethod(), getCallOptions()), request, responseObserver); + } + + /** + *
+     * Return information about this lightwalletd instance and the blockchain
+     * 
+ */ + public void getLightdInfo(cash.z.wallet.sdk.rpc.Service.Empty request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getGetLightdInfoMethod(), getCallOptions()), request, responseObserver); + } + + /** + *
+     * Testing-only, requires lightwalletd --ping-very-insecure (do not enable in production)
+     * 
+ */ + public void ping(cash.z.wallet.sdk.rpc.Service.Duration request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getPingMethod(), getCallOptions()), request, responseObserver); + } + } + + /** + */ + public static final class CompactTxStreamerBlockingStub extends io.grpc.stub.AbstractBlockingStub { + private CompactTxStreamerBlockingStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected CompactTxStreamerBlockingStub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new CompactTxStreamerBlockingStub(channel, callOptions); + } + + /** + *
+     * Return the height of the tip of the best chain
+     * 
+ */ + public cash.z.wallet.sdk.rpc.Service.BlockID getLatestBlock(cash.z.wallet.sdk.rpc.Service.ChainSpec request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getGetLatestBlockMethod(), getCallOptions(), request); + } + + /** + *
+     * Return the compact block corresponding to the given block identifier
+     * 
+ */ + public cash.z.wallet.sdk.rpc.CompactFormats.CompactBlock getBlock(cash.z.wallet.sdk.rpc.Service.BlockID request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getGetBlockMethod(), getCallOptions(), request); + } + + /** + *
+     * Return a list of consecutive compact blocks
+     * 
+ */ + public java.util.Iterator getBlockRange( + cash.z.wallet.sdk.rpc.Service.BlockRange request) { + return io.grpc.stub.ClientCalls.blockingServerStreamingCall( + getChannel(), getGetBlockRangeMethod(), getCallOptions(), request); + } + + /** + *
+     * Return the requested full (not compact) transaction (as from pirated)
+     * 
+ */ + public cash.z.wallet.sdk.rpc.Service.RawTransaction getTransaction(cash.z.wallet.sdk.rpc.Service.TxFilter request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getGetTransactionMethod(), getCallOptions(), request); + } + + /** + *
+     * Submit the given transaction to the Zcash network
+     * 
+ */ + public cash.z.wallet.sdk.rpc.Service.SendResponse sendTransaction(cash.z.wallet.sdk.rpc.Service.RawTransaction request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getSendTransactionMethod(), getCallOptions(), request); + } + + /** + *
+     * Return the txids corresponding to the given t-address within the given block range
+     * 
+ */ + public java.util.Iterator getTaddressTxids( + cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter request) { + return io.grpc.stub.ClientCalls.blockingServerStreamingCall( + getChannel(), getGetTaddressTxidsMethod(), getCallOptions(), request); + } + + /** + */ + public cash.z.wallet.sdk.rpc.Service.Balance getTaddressBalance(cash.z.wallet.sdk.rpc.Service.AddressList request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getGetTaddressBalanceMethod(), getCallOptions(), request); + } + + /** + *
+     * Return the compact transactions currently in the mempool; the results
+     * can be a few seconds out of date. If the Exclude list is empty, return
+     * all transactions; otherwise return all *except* those in the Exclude list
+     * (if any); this allows the client to avoid receiving transactions that it
+     * already has (from an earlier call to this rpc). The transaction IDs in the
+     * Exclude list can be shortened to any number of bytes to make the request
+     * more bandwidth-efficient; if two or more transactions in the mempool
+     * match a shortened txid, they are all sent (none is excluded). Transactions
+     * in the exclude list that don't exist in the mempool are ignored.
+     * 
+ */ + public java.util.Iterator getMempoolTx( + cash.z.wallet.sdk.rpc.Service.Exclude request) { + return io.grpc.stub.ClientCalls.blockingServerStreamingCall( + getChannel(), getGetMempoolTxMethod(), getCallOptions(), request); + } + + /** + *
+     * GetTreeState returns the note commitment tree state corresponding to the given block.
+     * See section 3.7 of the Zcash protocol specification. It returns several other useful
+     * values also (even though they can be obtained using GetBlock).
+     * The block can be specified by either height or hash.
+     * 
+ */ + public cash.z.wallet.sdk.rpc.Service.TreeState getTreeState(cash.z.wallet.sdk.rpc.Service.BlockID request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getGetTreeStateMethod(), getCallOptions(), request); + } + + /** + */ + public cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList getAddressUtxos(cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getGetAddressUtxosMethod(), getCallOptions(), request); + } + + /** + */ + public java.util.Iterator getAddressUtxosStream( + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg request) { + return io.grpc.stub.ClientCalls.blockingServerStreamingCall( + getChannel(), getGetAddressUtxosStreamMethod(), getCallOptions(), request); + } + + /** + *
+     * Return information about this lightwalletd instance and the blockchain
+     * 
+ */ + public cash.z.wallet.sdk.rpc.Service.LightdInfo getLightdInfo(cash.z.wallet.sdk.rpc.Service.Empty request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getGetLightdInfoMethod(), getCallOptions(), request); + } + + /** + *
+     * Testing-only, requires lightwalletd --ping-very-insecure (do not enable in production)
+     * 
+ */ + public cash.z.wallet.sdk.rpc.Service.PingResponse ping(cash.z.wallet.sdk.rpc.Service.Duration request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getPingMethod(), getCallOptions(), request); + } + } + + /** + */ + public static final class CompactTxStreamerFutureStub extends io.grpc.stub.AbstractFutureStub { + private CompactTxStreamerFutureStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected CompactTxStreamerFutureStub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new CompactTxStreamerFutureStub(channel, callOptions); + } + + /** + *
+     * Return the height of the tip of the best chain
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture getLatestBlock( + cash.z.wallet.sdk.rpc.Service.ChainSpec request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getGetLatestBlockMethod(), getCallOptions()), request); + } + + /** + *
+     * Return the compact block corresponding to the given block identifier
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture getBlock( + cash.z.wallet.sdk.rpc.Service.BlockID request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getGetBlockMethod(), getCallOptions()), request); + } + + /** + *
+     * Return the requested full (not compact) transaction (as from pirated)
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture getTransaction( + cash.z.wallet.sdk.rpc.Service.TxFilter request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getGetTransactionMethod(), getCallOptions()), request); + } + + /** + *
+     * Submit the given transaction to the Zcash network
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture sendTransaction( + cash.z.wallet.sdk.rpc.Service.RawTransaction request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getSendTransactionMethod(), getCallOptions()), request); + } + + /** + */ + public com.google.common.util.concurrent.ListenableFuture getTaddressBalance( + cash.z.wallet.sdk.rpc.Service.AddressList request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getGetTaddressBalanceMethod(), getCallOptions()), request); + } + + /** + *
+     * GetTreeState returns the note commitment tree state corresponding to the given block.
+     * See section 3.7 of the Zcash protocol specification. It returns several other useful
+     * values also (even though they can be obtained using GetBlock).
+     * The block can be specified by either height or hash.
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture getTreeState( + cash.z.wallet.sdk.rpc.Service.BlockID request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getGetTreeStateMethod(), getCallOptions()), request); + } + + /** + */ + public com.google.common.util.concurrent.ListenableFuture getAddressUtxos( + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getGetAddressUtxosMethod(), getCallOptions()), request); + } + + /** + *
+     * Return information about this lightwalletd instance and the blockchain
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture getLightdInfo( + cash.z.wallet.sdk.rpc.Service.Empty request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getGetLightdInfoMethod(), getCallOptions()), request); + } + + /** + *
+     * Testing-only, requires lightwalletd --ping-very-insecure (do not enable in production)
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture ping( + cash.z.wallet.sdk.rpc.Service.Duration request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getPingMethod(), getCallOptions()), request); + } + } + + private static final int METHODID_GET_LATEST_BLOCK = 0; + private static final int METHODID_GET_BLOCK = 1; + private static final int METHODID_GET_BLOCK_RANGE = 2; + private static final int METHODID_GET_TRANSACTION = 3; + private static final int METHODID_SEND_TRANSACTION = 4; + private static final int METHODID_GET_TADDRESS_TXIDS = 5; + private static final int METHODID_GET_TADDRESS_BALANCE = 6; + private static final int METHODID_GET_MEMPOOL_TX = 7; + private static final int METHODID_GET_TREE_STATE = 8; + private static final int METHODID_GET_ADDRESS_UTXOS = 9; + private static final int METHODID_GET_ADDRESS_UTXOS_STREAM = 10; + private static final int METHODID_GET_LIGHTD_INFO = 11; + private static final int METHODID_PING = 12; + private static final int METHODID_GET_TADDRESS_BALANCE_STREAM = 13; + + private static final class MethodHandlers implements + io.grpc.stub.ServerCalls.UnaryMethod, + io.grpc.stub.ServerCalls.ServerStreamingMethod, + io.grpc.stub.ServerCalls.ClientStreamingMethod, + io.grpc.stub.ServerCalls.BidiStreamingMethod { + private final CompactTxStreamerImplBase serviceImpl; + private final int methodId; + + MethodHandlers(CompactTxStreamerImplBase serviceImpl, int methodId) { + this.serviceImpl = serviceImpl; + this.methodId = methodId; + } + + @java.lang.Override + @java.lang.SuppressWarnings("unchecked") + public void invoke(Req request, io.grpc.stub.StreamObserver responseObserver) { + switch (methodId) { + case METHODID_GET_LATEST_BLOCK: + serviceImpl.getLatestBlock((cash.z.wallet.sdk.rpc.Service.ChainSpec) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_GET_BLOCK: + serviceImpl.getBlock((cash.z.wallet.sdk.rpc.Service.BlockID) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_GET_BLOCK_RANGE: + serviceImpl.getBlockRange((cash.z.wallet.sdk.rpc.Service.BlockRange) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_GET_TRANSACTION: + serviceImpl.getTransaction((cash.z.wallet.sdk.rpc.Service.TxFilter) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_SEND_TRANSACTION: + serviceImpl.sendTransaction((cash.z.wallet.sdk.rpc.Service.RawTransaction) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_GET_TADDRESS_TXIDS: + serviceImpl.getTaddressTxids((cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_GET_TADDRESS_BALANCE: + serviceImpl.getTaddressBalance((cash.z.wallet.sdk.rpc.Service.AddressList) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_GET_MEMPOOL_TX: + serviceImpl.getMempoolTx((cash.z.wallet.sdk.rpc.Service.Exclude) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_GET_TREE_STATE: + serviceImpl.getTreeState((cash.z.wallet.sdk.rpc.Service.BlockID) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_GET_ADDRESS_UTXOS: + serviceImpl.getAddressUtxos((cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_GET_ADDRESS_UTXOS_STREAM: + serviceImpl.getAddressUtxosStream((cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_GET_LIGHTD_INFO: + serviceImpl.getLightdInfo((cash.z.wallet.sdk.rpc.Service.Empty) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_PING: + serviceImpl.ping((cash.z.wallet.sdk.rpc.Service.Duration) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + default: + throw new AssertionError(); + } + } + + @java.lang.Override + @java.lang.SuppressWarnings("unchecked") + public io.grpc.stub.StreamObserver invoke( + io.grpc.stub.StreamObserver responseObserver) { + switch (methodId) { + case METHODID_GET_TADDRESS_BALANCE_STREAM: + return (io.grpc.stub.StreamObserver) serviceImpl.getTaddressBalanceStream( + (io.grpc.stub.StreamObserver) responseObserver); + default: + throw new AssertionError(); + } + } + } + + private static abstract class CompactTxStreamerBaseDescriptorSupplier + implements io.grpc.protobuf.ProtoFileDescriptorSupplier, io.grpc.protobuf.ProtoServiceDescriptorSupplier { + CompactTxStreamerBaseDescriptorSupplier() {} + + @java.lang.Override + public com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() { + return cash.z.wallet.sdk.rpc.Service.getDescriptor(); + } + + @java.lang.Override + public com.google.protobuf.Descriptors.ServiceDescriptor getServiceDescriptor() { + return getFileDescriptor().findServiceByName("CompactTxStreamer"); + } + } + + private static final class CompactTxStreamerFileDescriptorSupplier + extends CompactTxStreamerBaseDescriptorSupplier { + CompactTxStreamerFileDescriptorSupplier() {} + } + + private static final class CompactTxStreamerMethodDescriptorSupplier + extends CompactTxStreamerBaseDescriptorSupplier + implements io.grpc.protobuf.ProtoMethodDescriptorSupplier { + private final String methodName; + + CompactTxStreamerMethodDescriptorSupplier(String methodName) { + this.methodName = methodName; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.MethodDescriptor getMethodDescriptor() { + return getServiceDescriptor().findMethodByName(methodName); + } + } + + private static volatile io.grpc.ServiceDescriptor serviceDescriptor; + + public static io.grpc.ServiceDescriptor getServiceDescriptor() { + io.grpc.ServiceDescriptor result = serviceDescriptor; + if (result == null) { + synchronized (CompactTxStreamerGrpc.class) { + result = serviceDescriptor; + if (result == null) { + serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME) + .setSchemaDescriptor(new CompactTxStreamerFileDescriptorSupplier()) + .addMethod(getGetLatestBlockMethod()) + .addMethod(getGetBlockMethod()) + .addMethod(getGetBlockRangeMethod()) + .addMethod(getGetTransactionMethod()) + .addMethod(getSendTransactionMethod()) + .addMethod(getGetTaddressTxidsMethod()) + .addMethod(getGetTaddressBalanceMethod()) + .addMethod(getGetTaddressBalanceStreamMethod()) + .addMethod(getGetMempoolTxMethod()) + .addMethod(getGetTreeStateMethod()) + .addMethod(getGetAddressUtxosMethod()) + .addMethod(getGetAddressUtxosStreamMethod()) + .addMethod(getGetLightdInfoMethod()) + .addMethod(getPingMethod()) + .build(); + } + } + } + return result; + } +} diff --git a/src/main/java/cash/z/wallet/sdk/rpc/Darkside.java b/src/main/java/cash/z/wallet/sdk/rpc/Darkside.java new file mode 100644 index 00000000..d35f4ae7 --- /dev/null +++ b/src/main/java/cash/z/wallet/sdk/rpc/Darkside.java @@ -0,0 +1,3854 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: darkside.proto + +package cash.z.wallet.sdk.rpc; + +public final class Darkside { + private Darkside() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistryLite registry) { + } + + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + registerAllExtensions( + (com.google.protobuf.ExtensionRegistryLite) registry); + } + public interface DarksideMetaStateOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.DarksideMetaState) + com.google.protobuf.MessageOrBuilder { + + /** + * int32 saplingActivation = 1; + * @return The saplingActivation. + */ + int getSaplingActivation(); + + /** + * string branchID = 2; + * @return The branchID. + */ + java.lang.String getBranchID(); + /** + * string branchID = 2; + * @return The bytes for branchID. + */ + com.google.protobuf.ByteString + getBranchIDBytes(); + + /** + * string chainName = 3; + * @return The chainName. + */ + java.lang.String getChainName(); + /** + * string chainName = 3; + * @return The bytes for chainName. + */ + com.google.protobuf.ByteString + getChainNameBytes(); + } + /** + * Protobuf type {@code cash.z.wallet.sdk.rpc.DarksideMetaState} + */ + public static final class DarksideMetaState extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.DarksideMetaState) + DarksideMetaStateOrBuilder { + private static final long serialVersionUID = 0L; + // Use DarksideMetaState.newBuilder() to construct. + private DarksideMetaState(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private DarksideMetaState() { + branchID_ = ""; + chainName_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new DarksideMetaState(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private DarksideMetaState( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: { + + saplingActivation_ = input.readInt32(); + break; + } + case 18: { + java.lang.String s = input.readStringRequireUtf8(); + + branchID_ = s; + break; + } + case 26: { + java.lang.String s = input.readStringRequireUtf8(); + + chainName_ = s; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideMetaState_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideMetaState_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState.class, cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState.Builder.class); + } + + public static final int SAPLINGACTIVATION_FIELD_NUMBER = 1; + private int saplingActivation_; + /** + * int32 saplingActivation = 1; + * @return The saplingActivation. + */ + @java.lang.Override + public int getSaplingActivation() { + return saplingActivation_; + } + + public static final int BRANCHID_FIELD_NUMBER = 2; + private volatile java.lang.Object branchID_; + /** + * string branchID = 2; + * @return The branchID. + */ + @java.lang.Override + public java.lang.String getBranchID() { + java.lang.Object ref = branchID_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + branchID_ = s; + return s; + } + } + /** + * string branchID = 2; + * @return The bytes for branchID. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getBranchIDBytes() { + java.lang.Object ref = branchID_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + branchID_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int CHAINNAME_FIELD_NUMBER = 3; + private volatile java.lang.Object chainName_; + /** + * string chainName = 3; + * @return The chainName. + */ + @java.lang.Override + public java.lang.String getChainName() { + java.lang.Object ref = chainName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + chainName_ = s; + return s; + } + } + /** + * string chainName = 3; + * @return The bytes for chainName. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getChainNameBytes() { + java.lang.Object ref = chainName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + chainName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (saplingActivation_ != 0) { + output.writeInt32(1, saplingActivation_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(branchID_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, branchID_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(chainName_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 3, chainName_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (saplingActivation_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(1, saplingActivation_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(branchID_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, branchID_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(chainName_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, chainName_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState other = (cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState) obj; + + if (getSaplingActivation() + != other.getSaplingActivation()) return false; + if (!getBranchID() + .equals(other.getBranchID())) return false; + if (!getChainName() + .equals(other.getChainName())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + SAPLINGACTIVATION_FIELD_NUMBER; + hash = (53 * hash) + getSaplingActivation(); + hash = (37 * hash) + BRANCHID_FIELD_NUMBER; + hash = (53 * hash) + getBranchID().hashCode(); + hash = (37 * hash) + CHAINNAME_FIELD_NUMBER; + hash = (53 * hash) + getChainName().hashCode(); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code cash.z.wallet.sdk.rpc.DarksideMetaState} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.DarksideMetaState) + cash.z.wallet.sdk.rpc.Darkside.DarksideMetaStateOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideMetaState_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideMetaState_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState.class, cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + saplingActivation_ = 0; + + branchID_ = ""; + + chainName_ = ""; + + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideMetaState_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState build() { + cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState buildPartial() { + cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState result = new cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState(this); + result.saplingActivation_ = saplingActivation_; + result.branchID_ = branchID_; + result.chainName_ = chainName_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState) { + return mergeFrom((cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState other) { + if (other == cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState.getDefaultInstance()) return this; + if (other.getSaplingActivation() != 0) { + setSaplingActivation(other.getSaplingActivation()); + } + if (!other.getBranchID().isEmpty()) { + branchID_ = other.branchID_; + onChanged(); + } + if (!other.getChainName().isEmpty()) { + chainName_ = other.chainName_; + onChanged(); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private int saplingActivation_ ; + /** + * int32 saplingActivation = 1; + * @return The saplingActivation. + */ + @java.lang.Override + public int getSaplingActivation() { + return saplingActivation_; + } + /** + * int32 saplingActivation = 1; + * @param value The saplingActivation to set. + * @return This builder for chaining. + */ + public Builder setSaplingActivation(int value) { + + saplingActivation_ = value; + onChanged(); + return this; + } + /** + * int32 saplingActivation = 1; + * @return This builder for chaining. + */ + public Builder clearSaplingActivation() { + + saplingActivation_ = 0; + onChanged(); + return this; + } + + private java.lang.Object branchID_ = ""; + /** + * string branchID = 2; + * @return The branchID. + */ + public java.lang.String getBranchID() { + java.lang.Object ref = branchID_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + branchID_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * string branchID = 2; + * @return The bytes for branchID. + */ + public com.google.protobuf.ByteString + getBranchIDBytes() { + java.lang.Object ref = branchID_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + branchID_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string branchID = 2; + * @param value The branchID to set. + * @return This builder for chaining. + */ + public Builder setBranchID( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + branchID_ = value; + onChanged(); + return this; + } + /** + * string branchID = 2; + * @return This builder for chaining. + */ + public Builder clearBranchID() { + + branchID_ = getDefaultInstance().getBranchID(); + onChanged(); + return this; + } + /** + * string branchID = 2; + * @param value The bytes for branchID to set. + * @return This builder for chaining. + */ + public Builder setBranchIDBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + branchID_ = value; + onChanged(); + return this; + } + + private java.lang.Object chainName_ = ""; + /** + * string chainName = 3; + * @return The chainName. + */ + public java.lang.String getChainName() { + java.lang.Object ref = chainName_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + chainName_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * string chainName = 3; + * @return The bytes for chainName. + */ + public com.google.protobuf.ByteString + getChainNameBytes() { + java.lang.Object ref = chainName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + chainName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string chainName = 3; + * @param value The chainName to set. + * @return This builder for chaining. + */ + public Builder setChainName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + chainName_ = value; + onChanged(); + return this; + } + /** + * string chainName = 3; + * @return This builder for chaining. + */ + public Builder clearChainName() { + + chainName_ = getDefaultInstance().getChainName(); + onChanged(); + return this; + } + /** + * string chainName = 3; + * @param value The bytes for chainName to set. + * @return This builder for chaining. + */ + public Builder setChainNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + chainName_ = value; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.DarksideMetaState) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.DarksideMetaState) + private static final cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState(); + } + + public static cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public DarksideMetaState parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new DarksideMetaState(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface DarksideBlockOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.DarksideBlock) + com.google.protobuf.MessageOrBuilder { + + /** + * string block = 1; + * @return The block. + */ + java.lang.String getBlock(); + /** + * string block = 1; + * @return The bytes for block. + */ + com.google.protobuf.ByteString + getBlockBytes(); + } + /** + *
+   * A block is a hex-encoded string.
+   * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.DarksideBlock} + */ + public static final class DarksideBlock extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.DarksideBlock) + DarksideBlockOrBuilder { + private static final long serialVersionUID = 0L; + // Use DarksideBlock.newBuilder() to construct. + private DarksideBlock(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private DarksideBlock() { + block_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new DarksideBlock(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private DarksideBlock( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + java.lang.String s = input.readStringRequireUtf8(); + + block_ = s; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideBlock_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideBlock_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Darkside.DarksideBlock.class, cash.z.wallet.sdk.rpc.Darkside.DarksideBlock.Builder.class); + } + + public static final int BLOCK_FIELD_NUMBER = 1; + private volatile java.lang.Object block_; + /** + * string block = 1; + * @return The block. + */ + @java.lang.Override + public java.lang.String getBlock() { + java.lang.Object ref = block_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + block_ = s; + return s; + } + } + /** + * string block = 1; + * @return The bytes for block. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getBlockBytes() { + java.lang.Object ref = block_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + block_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(block_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, block_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(block_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, block_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.Darkside.DarksideBlock)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.Darkside.DarksideBlock other = (cash.z.wallet.sdk.rpc.Darkside.DarksideBlock) obj; + + if (!getBlock() + .equals(other.getBlock())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + BLOCK_FIELD_NUMBER; + hash = (53 * hash) + getBlock().hashCode(); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.Darkside.DarksideBlock parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideBlock parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideBlock parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideBlock parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideBlock parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideBlock parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideBlock parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideBlock parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideBlock parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideBlock parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideBlock parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideBlock parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.Darkside.DarksideBlock prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * A block is a hex-encoded string.
+     * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.DarksideBlock} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.DarksideBlock) + cash.z.wallet.sdk.rpc.Darkside.DarksideBlockOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideBlock_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideBlock_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Darkside.DarksideBlock.class, cash.z.wallet.sdk.rpc.Darkside.DarksideBlock.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.Darkside.DarksideBlock.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + block_ = ""; + + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideBlock_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Darkside.DarksideBlock getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.Darkside.DarksideBlock.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Darkside.DarksideBlock build() { + cash.z.wallet.sdk.rpc.Darkside.DarksideBlock result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Darkside.DarksideBlock buildPartial() { + cash.z.wallet.sdk.rpc.Darkside.DarksideBlock result = new cash.z.wallet.sdk.rpc.Darkside.DarksideBlock(this); + result.block_ = block_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.Darkside.DarksideBlock) { + return mergeFrom((cash.z.wallet.sdk.rpc.Darkside.DarksideBlock)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.Darkside.DarksideBlock other) { + if (other == cash.z.wallet.sdk.rpc.Darkside.DarksideBlock.getDefaultInstance()) return this; + if (!other.getBlock().isEmpty()) { + block_ = other.block_; + onChanged(); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.Darkside.DarksideBlock parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.Darkside.DarksideBlock) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private java.lang.Object block_ = ""; + /** + * string block = 1; + * @return The block. + */ + public java.lang.String getBlock() { + java.lang.Object ref = block_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + block_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * string block = 1; + * @return The bytes for block. + */ + public com.google.protobuf.ByteString + getBlockBytes() { + java.lang.Object ref = block_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + block_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string block = 1; + * @param value The block to set. + * @return This builder for chaining. + */ + public Builder setBlock( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + block_ = value; + onChanged(); + return this; + } + /** + * string block = 1; + * @return This builder for chaining. + */ + public Builder clearBlock() { + + block_ = getDefaultInstance().getBlock(); + onChanged(); + return this; + } + /** + * string block = 1; + * @param value The bytes for block to set. + * @return This builder for chaining. + */ + public Builder setBlockBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + block_ = value; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.DarksideBlock) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.DarksideBlock) + private static final cash.z.wallet.sdk.rpc.Darkside.DarksideBlock DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.Darkside.DarksideBlock(); + } + + public static cash.z.wallet.sdk.rpc.Darkside.DarksideBlock getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public DarksideBlock parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new DarksideBlock(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Darkside.DarksideBlock getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface DarksideBlocksURLOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.DarksideBlocksURL) + com.google.protobuf.MessageOrBuilder { + + /** + * string url = 1; + * @return The url. + */ + java.lang.String getUrl(); + /** + * string url = 1; + * @return The bytes for url. + */ + com.google.protobuf.ByteString + getUrlBytes(); + } + /** + *
+   * DarksideBlocksURL is typically something like:
+   * https://raw.githubusercontent.com/zcash-hackworks/darksidewalletd-test-data/master/basic-reorg/before-reorg.txt
+   * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.DarksideBlocksURL} + */ + public static final class DarksideBlocksURL extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.DarksideBlocksURL) + DarksideBlocksURLOrBuilder { + private static final long serialVersionUID = 0L; + // Use DarksideBlocksURL.newBuilder() to construct. + private DarksideBlocksURL(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private DarksideBlocksURL() { + url_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new DarksideBlocksURL(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private DarksideBlocksURL( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + java.lang.String s = input.readStringRequireUtf8(); + + url_ = s; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideBlocksURL_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideBlocksURL_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL.class, cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL.Builder.class); + } + + public static final int URL_FIELD_NUMBER = 1; + private volatile java.lang.Object url_; + /** + * string url = 1; + * @return The url. + */ + @java.lang.Override + public java.lang.String getUrl() { + java.lang.Object ref = url_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + url_ = s; + return s; + } + } + /** + * string url = 1; + * @return The bytes for url. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getUrlBytes() { + java.lang.Object ref = url_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + url_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(url_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, url_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(url_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, url_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL other = (cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL) obj; + + if (!getUrl() + .equals(other.getUrl())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + URL_FIELD_NUMBER; + hash = (53 * hash) + getUrl().hashCode(); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * DarksideBlocksURL is typically something like:
+     * https://raw.githubusercontent.com/zcash-hackworks/darksidewalletd-test-data/master/basic-reorg/before-reorg.txt
+     * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.DarksideBlocksURL} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.DarksideBlocksURL) + cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURLOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideBlocksURL_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideBlocksURL_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL.class, cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + url_ = ""; + + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideBlocksURL_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL build() { + cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL buildPartial() { + cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL result = new cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL(this); + result.url_ = url_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL) { + return mergeFrom((cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL other) { + if (other == cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL.getDefaultInstance()) return this; + if (!other.getUrl().isEmpty()) { + url_ = other.url_; + onChanged(); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private java.lang.Object url_ = ""; + /** + * string url = 1; + * @return The url. + */ + public java.lang.String getUrl() { + java.lang.Object ref = url_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + url_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * string url = 1; + * @return The bytes for url. + */ + public com.google.protobuf.ByteString + getUrlBytes() { + java.lang.Object ref = url_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + url_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string url = 1; + * @param value The url to set. + * @return This builder for chaining. + */ + public Builder setUrl( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + url_ = value; + onChanged(); + return this; + } + /** + * string url = 1; + * @return This builder for chaining. + */ + public Builder clearUrl() { + + url_ = getDefaultInstance().getUrl(); + onChanged(); + return this; + } + /** + * string url = 1; + * @param value The bytes for url to set. + * @return This builder for chaining. + */ + public Builder setUrlBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + url_ = value; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.DarksideBlocksURL) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.DarksideBlocksURL) + private static final cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL(); + } + + public static cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public DarksideBlocksURL parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new DarksideBlocksURL(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface DarksideTransactionsURLOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.DarksideTransactionsURL) + com.google.protobuf.MessageOrBuilder { + + /** + * int32 height = 1; + * @return The height. + */ + int getHeight(); + + /** + * string url = 2; + * @return The url. + */ + java.lang.String getUrl(); + /** + * string url = 2; + * @return The bytes for url. + */ + com.google.protobuf.ByteString + getUrlBytes(); + } + /** + *
+   * DarksideTransactionsURL refers to an HTTP source that contains a list
+   * of hex-encoded transactions, one per line, that are to be associated
+   * with the given height (fake-mined into the block at that height)
+   * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.DarksideTransactionsURL} + */ + public static final class DarksideTransactionsURL extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.DarksideTransactionsURL) + DarksideTransactionsURLOrBuilder { + private static final long serialVersionUID = 0L; + // Use DarksideTransactionsURL.newBuilder() to construct. + private DarksideTransactionsURL(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private DarksideTransactionsURL() { + url_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new DarksideTransactionsURL(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private DarksideTransactionsURL( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: { + + height_ = input.readInt32(); + break; + } + case 18: { + java.lang.String s = input.readStringRequireUtf8(); + + url_ = s; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideTransactionsURL_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideTransactionsURL_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL.class, cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL.Builder.class); + } + + public static final int HEIGHT_FIELD_NUMBER = 1; + private int height_; + /** + * int32 height = 1; + * @return The height. + */ + @java.lang.Override + public int getHeight() { + return height_; + } + + public static final int URL_FIELD_NUMBER = 2; + private volatile java.lang.Object url_; + /** + * string url = 2; + * @return The url. + */ + @java.lang.Override + public java.lang.String getUrl() { + java.lang.Object ref = url_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + url_ = s; + return s; + } + } + /** + * string url = 2; + * @return The bytes for url. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getUrlBytes() { + java.lang.Object ref = url_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + url_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (height_ != 0) { + output.writeInt32(1, height_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(url_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, url_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (height_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(1, height_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(url_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, url_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL other = (cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL) obj; + + if (getHeight() + != other.getHeight()) return false; + if (!getUrl() + .equals(other.getUrl())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + HEIGHT_FIELD_NUMBER; + hash = (53 * hash) + getHeight(); + hash = (37 * hash) + URL_FIELD_NUMBER; + hash = (53 * hash) + getUrl().hashCode(); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * DarksideTransactionsURL refers to an HTTP source that contains a list
+     * of hex-encoded transactions, one per line, that are to be associated
+     * with the given height (fake-mined into the block at that height)
+     * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.DarksideTransactionsURL} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.DarksideTransactionsURL) + cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURLOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideTransactionsURL_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideTransactionsURL_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL.class, cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + height_ = 0; + + url_ = ""; + + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideTransactionsURL_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL build() { + cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL buildPartial() { + cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL result = new cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL(this); + result.height_ = height_; + result.url_ = url_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL) { + return mergeFrom((cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL other) { + if (other == cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL.getDefaultInstance()) return this; + if (other.getHeight() != 0) { + setHeight(other.getHeight()); + } + if (!other.getUrl().isEmpty()) { + url_ = other.url_; + onChanged(); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private int height_ ; + /** + * int32 height = 1; + * @return The height. + */ + @java.lang.Override + public int getHeight() { + return height_; + } + /** + * int32 height = 1; + * @param value The height to set. + * @return This builder for chaining. + */ + public Builder setHeight(int value) { + + height_ = value; + onChanged(); + return this; + } + /** + * int32 height = 1; + * @return This builder for chaining. + */ + public Builder clearHeight() { + + height_ = 0; + onChanged(); + return this; + } + + private java.lang.Object url_ = ""; + /** + * string url = 2; + * @return The url. + */ + public java.lang.String getUrl() { + java.lang.Object ref = url_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + url_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * string url = 2; + * @return The bytes for url. + */ + public com.google.protobuf.ByteString + getUrlBytes() { + java.lang.Object ref = url_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + url_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string url = 2; + * @param value The url to set. + * @return This builder for chaining. + */ + public Builder setUrl( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + url_ = value; + onChanged(); + return this; + } + /** + * string url = 2; + * @return This builder for chaining. + */ + public Builder clearUrl() { + + url_ = getDefaultInstance().getUrl(); + onChanged(); + return this; + } + /** + * string url = 2; + * @param value The bytes for url to set. + * @return This builder for chaining. + */ + public Builder setUrlBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + url_ = value; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.DarksideTransactionsURL) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.DarksideTransactionsURL) + private static final cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL(); + } + + public static cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public DarksideTransactionsURL parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new DarksideTransactionsURL(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface DarksideHeightOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.DarksideHeight) + com.google.protobuf.MessageOrBuilder { + + /** + * int32 height = 1; + * @return The height. + */ + int getHeight(); + } + /** + * Protobuf type {@code cash.z.wallet.sdk.rpc.DarksideHeight} + */ + public static final class DarksideHeight extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.DarksideHeight) + DarksideHeightOrBuilder { + private static final long serialVersionUID = 0L; + // Use DarksideHeight.newBuilder() to construct. + private DarksideHeight(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private DarksideHeight() { + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new DarksideHeight(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private DarksideHeight( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: { + + height_ = input.readInt32(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideHeight_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideHeight_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Darkside.DarksideHeight.class, cash.z.wallet.sdk.rpc.Darkside.DarksideHeight.Builder.class); + } + + public static final int HEIGHT_FIELD_NUMBER = 1; + private int height_; + /** + * int32 height = 1; + * @return The height. + */ + @java.lang.Override + public int getHeight() { + return height_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (height_ != 0) { + output.writeInt32(1, height_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (height_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(1, height_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.Darkside.DarksideHeight)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.Darkside.DarksideHeight other = (cash.z.wallet.sdk.rpc.Darkside.DarksideHeight) obj; + + if (getHeight() + != other.getHeight()) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + HEIGHT_FIELD_NUMBER; + hash = (53 * hash) + getHeight(); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.Darkside.DarksideHeight parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideHeight parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideHeight parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideHeight parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideHeight parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideHeight parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideHeight parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideHeight parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideHeight parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideHeight parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideHeight parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideHeight parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.Darkside.DarksideHeight prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code cash.z.wallet.sdk.rpc.DarksideHeight} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.DarksideHeight) + cash.z.wallet.sdk.rpc.Darkside.DarksideHeightOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideHeight_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideHeight_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Darkside.DarksideHeight.class, cash.z.wallet.sdk.rpc.Darkside.DarksideHeight.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.Darkside.DarksideHeight.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + height_ = 0; + + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideHeight_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Darkside.DarksideHeight getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.Darkside.DarksideHeight.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Darkside.DarksideHeight build() { + cash.z.wallet.sdk.rpc.Darkside.DarksideHeight result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Darkside.DarksideHeight buildPartial() { + cash.z.wallet.sdk.rpc.Darkside.DarksideHeight result = new cash.z.wallet.sdk.rpc.Darkside.DarksideHeight(this); + result.height_ = height_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.Darkside.DarksideHeight) { + return mergeFrom((cash.z.wallet.sdk.rpc.Darkside.DarksideHeight)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.Darkside.DarksideHeight other) { + if (other == cash.z.wallet.sdk.rpc.Darkside.DarksideHeight.getDefaultInstance()) return this; + if (other.getHeight() != 0) { + setHeight(other.getHeight()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.Darkside.DarksideHeight parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.Darkside.DarksideHeight) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private int height_ ; + /** + * int32 height = 1; + * @return The height. + */ + @java.lang.Override + public int getHeight() { + return height_; + } + /** + * int32 height = 1; + * @param value The height to set. + * @return This builder for chaining. + */ + public Builder setHeight(int value) { + + height_ = value; + onChanged(); + return this; + } + /** + * int32 height = 1; + * @return This builder for chaining. + */ + public Builder clearHeight() { + + height_ = 0; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.DarksideHeight) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.DarksideHeight) + private static final cash.z.wallet.sdk.rpc.Darkside.DarksideHeight DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.Darkside.DarksideHeight(); + } + + public static cash.z.wallet.sdk.rpc.Darkside.DarksideHeight getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public DarksideHeight parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new DarksideHeight(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Darkside.DarksideHeight getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface DarksideEmptyBlocksOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.DarksideEmptyBlocks) + com.google.protobuf.MessageOrBuilder { + + /** + * int32 height = 1; + * @return The height. + */ + int getHeight(); + + /** + * int32 nonce = 2; + * @return The nonce. + */ + int getNonce(); + + /** + * int32 count = 3; + * @return The count. + */ + int getCount(); + } + /** + * Protobuf type {@code cash.z.wallet.sdk.rpc.DarksideEmptyBlocks} + */ + public static final class DarksideEmptyBlocks extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.DarksideEmptyBlocks) + DarksideEmptyBlocksOrBuilder { + private static final long serialVersionUID = 0L; + // Use DarksideEmptyBlocks.newBuilder() to construct. + private DarksideEmptyBlocks(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private DarksideEmptyBlocks() { + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new DarksideEmptyBlocks(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private DarksideEmptyBlocks( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: { + + height_ = input.readInt32(); + break; + } + case 16: { + + nonce_ = input.readInt32(); + break; + } + case 24: { + + count_ = input.readInt32(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideEmptyBlocks_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideEmptyBlocks_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks.class, cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks.Builder.class); + } + + public static final int HEIGHT_FIELD_NUMBER = 1; + private int height_; + /** + * int32 height = 1; + * @return The height. + */ + @java.lang.Override + public int getHeight() { + return height_; + } + + public static final int NONCE_FIELD_NUMBER = 2; + private int nonce_; + /** + * int32 nonce = 2; + * @return The nonce. + */ + @java.lang.Override + public int getNonce() { + return nonce_; + } + + public static final int COUNT_FIELD_NUMBER = 3; + private int count_; + /** + * int32 count = 3; + * @return The count. + */ + @java.lang.Override + public int getCount() { + return count_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (height_ != 0) { + output.writeInt32(1, height_); + } + if (nonce_ != 0) { + output.writeInt32(2, nonce_); + } + if (count_ != 0) { + output.writeInt32(3, count_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (height_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(1, height_); + } + if (nonce_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(2, nonce_); + } + if (count_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(3, count_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks other = (cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks) obj; + + if (getHeight() + != other.getHeight()) return false; + if (getNonce() + != other.getNonce()) return false; + if (getCount() + != other.getCount()) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + HEIGHT_FIELD_NUMBER; + hash = (53 * hash) + getHeight(); + hash = (37 * hash) + NONCE_FIELD_NUMBER; + hash = (53 * hash) + getNonce(); + hash = (37 * hash) + COUNT_FIELD_NUMBER; + hash = (53 * hash) + getCount(); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code cash.z.wallet.sdk.rpc.DarksideEmptyBlocks} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.DarksideEmptyBlocks) + cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocksOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideEmptyBlocks_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideEmptyBlocks_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks.class, cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + height_ = 0; + + nonce_ = 0; + + count_ = 0; + + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.Darkside.internal_static_cash_z_wallet_sdk_rpc_DarksideEmptyBlocks_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks build() { + cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks buildPartial() { + cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks result = new cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks(this); + result.height_ = height_; + result.nonce_ = nonce_; + result.count_ = count_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks) { + return mergeFrom((cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks other) { + if (other == cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks.getDefaultInstance()) return this; + if (other.getHeight() != 0) { + setHeight(other.getHeight()); + } + if (other.getNonce() != 0) { + setNonce(other.getNonce()); + } + if (other.getCount() != 0) { + setCount(other.getCount()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private int height_ ; + /** + * int32 height = 1; + * @return The height. + */ + @java.lang.Override + public int getHeight() { + return height_; + } + /** + * int32 height = 1; + * @param value The height to set. + * @return This builder for chaining. + */ + public Builder setHeight(int value) { + + height_ = value; + onChanged(); + return this; + } + /** + * int32 height = 1; + * @return This builder for chaining. + */ + public Builder clearHeight() { + + height_ = 0; + onChanged(); + return this; + } + + private int nonce_ ; + /** + * int32 nonce = 2; + * @return The nonce. + */ + @java.lang.Override + public int getNonce() { + return nonce_; + } + /** + * int32 nonce = 2; + * @param value The nonce to set. + * @return This builder for chaining. + */ + public Builder setNonce(int value) { + + nonce_ = value; + onChanged(); + return this; + } + /** + * int32 nonce = 2; + * @return This builder for chaining. + */ + public Builder clearNonce() { + + nonce_ = 0; + onChanged(); + return this; + } + + private int count_ ; + /** + * int32 count = 3; + * @return The count. + */ + @java.lang.Override + public int getCount() { + return count_; + } + /** + * int32 count = 3; + * @param value The count to set. + * @return This builder for chaining. + */ + public Builder setCount(int value) { + + count_ = value; + onChanged(); + return this; + } + /** + * int32 count = 3; + * @return This builder for chaining. + */ + public Builder clearCount() { + + count_ = 0; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.DarksideEmptyBlocks) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.DarksideEmptyBlocks) + private static final cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks(); + } + + public static cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public DarksideEmptyBlocks parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new DarksideEmptyBlocks(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_DarksideMetaState_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_DarksideMetaState_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_DarksideBlock_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_DarksideBlock_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_DarksideBlocksURL_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_DarksideBlocksURL_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_DarksideTransactionsURL_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_DarksideTransactionsURL_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_DarksideHeight_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_DarksideHeight_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_DarksideEmptyBlocks_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_DarksideEmptyBlocks_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + java.lang.String[] descriptorData = { + "\n\016darkside.proto\022\025cash.z.wallet.sdk.rpc\032" + + "\rservice.proto\"S\n\021DarksideMetaState\022\031\n\021s" + + "aplingActivation\030\001 \001(\005\022\020\n\010branchID\030\002 \001(\t" + + "\022\021\n\tchainName\030\003 \001(\t\"\036\n\rDarksideBlock\022\r\n\005" + + "block\030\001 \001(\t\" \n\021DarksideBlocksURL\022\013\n\003url\030" + + "\001 \001(\t\"6\n\027DarksideTransactionsURL\022\016\n\006heig" + + "ht\030\001 \001(\005\022\013\n\003url\030\002 \001(\t\" \n\016DarksideHeight\022" + + "\016\n\006height\030\001 \001(\005\"C\n\023DarksideEmptyBlocks\022\016" + + "\n\006height\030\001 \001(\005\022\r\n\005nonce\030\002 \001(\005\022\r\n\005count\030\003" + + " \001(\0052\332\006\n\020DarksideStreamer\022Q\n\005Reset\022(.cas" + + "h.z.wallet.sdk.rpc.DarksideMetaState\032\034.c" + + "ash.z.wallet.sdk.rpc.Empty\"\000\022[\n\021StageBlo" + + "cksStream\022$.cash.z.wallet.sdk.rpc.Darksi" + + "deBlock\032\034.cash.z.wallet.sdk.rpc.Empty\"\000(" + + "\001\022W\n\013StageBlocks\022(.cash.z.wallet.sdk.rpc" + + ".DarksideBlocksURL\032\034.cash.z.wallet.sdk.r" + + "pc.Empty\"\000\022_\n\021StageBlocksCreate\022*.cash.z" + + ".wallet.sdk.rpc.DarksideEmptyBlocks\032\034.ca" + + "sh.z.wallet.sdk.rpc.Empty\"\000\022b\n\027StageTran" + + "sactionsStream\022%.cash.z.wallet.sdk.rpc.R" + + "awTransaction\032\034.cash.z.wallet.sdk.rpc.Em" + + "pty\"\000(\001\022c\n\021StageTransactions\022..cash.z.wa" + + "llet.sdk.rpc.DarksideTransactionsURL\032\034.c" + + "ash.z.wallet.sdk.rpc.Empty\"\000\022T\n\013ApplySta" + + "ged\022%.cash.z.wallet.sdk.rpc.DarksideHeig" + + "ht\032\034.cash.z.wallet.sdk.rpc.Empty\"\000\022b\n\027Ge" + + "tIncomingTransactions\022\034.cash.z.wallet.sd" + + "k.rpc.Empty\032%.cash.z.wallet.sdk.rpc.RawT" + + "ransaction\"\0000\001\022Y\n\031ClearIncomingTransacti" + + "ons\022\034.cash.z.wallet.sdk.rpc.Empty\032\034.cash" + + ".z.wallet.sdk.rpc.Empty\"\000B\033Z\026lightwallet" + + "d/walletrpc\272\002\000b\006proto3" + }; + descriptor = com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + cash.z.wallet.sdk.rpc.Service.getDescriptor(), + }); + internal_static_cash_z_wallet_sdk_rpc_DarksideMetaState_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_cash_z_wallet_sdk_rpc_DarksideMetaState_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_DarksideMetaState_descriptor, + new java.lang.String[] { "SaplingActivation", "BranchID", "ChainName", }); + internal_static_cash_z_wallet_sdk_rpc_DarksideBlock_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_cash_z_wallet_sdk_rpc_DarksideBlock_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_DarksideBlock_descriptor, + new java.lang.String[] { "Block", }); + internal_static_cash_z_wallet_sdk_rpc_DarksideBlocksURL_descriptor = + getDescriptor().getMessageTypes().get(2); + internal_static_cash_z_wallet_sdk_rpc_DarksideBlocksURL_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_DarksideBlocksURL_descriptor, + new java.lang.String[] { "Url", }); + internal_static_cash_z_wallet_sdk_rpc_DarksideTransactionsURL_descriptor = + getDescriptor().getMessageTypes().get(3); + internal_static_cash_z_wallet_sdk_rpc_DarksideTransactionsURL_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_DarksideTransactionsURL_descriptor, + new java.lang.String[] { "Height", "Url", }); + internal_static_cash_z_wallet_sdk_rpc_DarksideHeight_descriptor = + getDescriptor().getMessageTypes().get(4); + internal_static_cash_z_wallet_sdk_rpc_DarksideHeight_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_DarksideHeight_descriptor, + new java.lang.String[] { "Height", }); + internal_static_cash_z_wallet_sdk_rpc_DarksideEmptyBlocks_descriptor = + getDescriptor().getMessageTypes().get(5); + internal_static_cash_z_wallet_sdk_rpc_DarksideEmptyBlocks_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_DarksideEmptyBlocks_descriptor, + new java.lang.String[] { "Height", "Nonce", "Count", }); + cash.z.wallet.sdk.rpc.Service.getDescriptor(); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/src/main/java/cash/z/wallet/sdk/rpc/DarksideStreamerGrpc.java b/src/main/java/cash/z/wallet/sdk/rpc/DarksideStreamerGrpc.java new file mode 100644 index 00000000..5b180bea --- /dev/null +++ b/src/main/java/cash/z/wallet/sdk/rpc/DarksideStreamerGrpc.java @@ -0,0 +1,1086 @@ +package cash.z.wallet.sdk.rpc; + +import static io.grpc.MethodDescriptor.generateFullMethodName; + +/** + *
+ * Darksidewalletd maintains two staging areas, blocks and transactions. The
+ * Stage*() gRPCs add items to the staging area; ApplyStaged() "applies" everything
+ * in the staging area to the working (operational) state that the mock zcashd
+ * serves; transactions are placed into their corresponding blocks (by height).
+ * 
+ */ +@javax.annotation.Generated( + value = "by gRPC proto compiler (version 1.45.1)", + comments = "Source: darkside.proto") +@io.grpc.stub.annotations.GrpcGenerated +public final class DarksideStreamerGrpc { + + private DarksideStreamerGrpc() {} + + public static final String SERVICE_NAME = "cash.z.wallet.sdk.rpc.DarksideStreamer"; + + // Static method descriptors that strictly reflect the proto. + private static volatile io.grpc.MethodDescriptor getResetMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "Reset", + requestType = cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState.class, + responseType = cash.z.wallet.sdk.rpc.Service.Empty.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getResetMethod() { + io.grpc.MethodDescriptor getResetMethod; + if ((getResetMethod = DarksideStreamerGrpc.getResetMethod) == null) { + synchronized (DarksideStreamerGrpc.class) { + if ((getResetMethod = DarksideStreamerGrpc.getResetMethod) == null) { + DarksideStreamerGrpc.getResetMethod = getResetMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "Reset")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.Empty.getDefaultInstance())) + .setSchemaDescriptor(new DarksideStreamerMethodDescriptorSupplier("Reset")) + .build(); + } + } + } + return getResetMethod; + } + + private static volatile io.grpc.MethodDescriptor getStageBlocksStreamMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "StageBlocksStream", + requestType = cash.z.wallet.sdk.rpc.Darkside.DarksideBlock.class, + responseType = cash.z.wallet.sdk.rpc.Service.Empty.class, + methodType = io.grpc.MethodDescriptor.MethodType.CLIENT_STREAMING) + public static io.grpc.MethodDescriptor getStageBlocksStreamMethod() { + io.grpc.MethodDescriptor getStageBlocksStreamMethod; + if ((getStageBlocksStreamMethod = DarksideStreamerGrpc.getStageBlocksStreamMethod) == null) { + synchronized (DarksideStreamerGrpc.class) { + if ((getStageBlocksStreamMethod = DarksideStreamerGrpc.getStageBlocksStreamMethod) == null) { + DarksideStreamerGrpc.getStageBlocksStreamMethod = getStageBlocksStreamMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.CLIENT_STREAMING) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "StageBlocksStream")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Darkside.DarksideBlock.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.Empty.getDefaultInstance())) + .setSchemaDescriptor(new DarksideStreamerMethodDescriptorSupplier("StageBlocksStream")) + .build(); + } + } + } + return getStageBlocksStreamMethod; + } + + private static volatile io.grpc.MethodDescriptor getStageBlocksMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "StageBlocks", + requestType = cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL.class, + responseType = cash.z.wallet.sdk.rpc.Service.Empty.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getStageBlocksMethod() { + io.grpc.MethodDescriptor getStageBlocksMethod; + if ((getStageBlocksMethod = DarksideStreamerGrpc.getStageBlocksMethod) == null) { + synchronized (DarksideStreamerGrpc.class) { + if ((getStageBlocksMethod = DarksideStreamerGrpc.getStageBlocksMethod) == null) { + DarksideStreamerGrpc.getStageBlocksMethod = getStageBlocksMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "StageBlocks")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.Empty.getDefaultInstance())) + .setSchemaDescriptor(new DarksideStreamerMethodDescriptorSupplier("StageBlocks")) + .build(); + } + } + } + return getStageBlocksMethod; + } + + private static volatile io.grpc.MethodDescriptor getStageBlocksCreateMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "StageBlocksCreate", + requestType = cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks.class, + responseType = cash.z.wallet.sdk.rpc.Service.Empty.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getStageBlocksCreateMethod() { + io.grpc.MethodDescriptor getStageBlocksCreateMethod; + if ((getStageBlocksCreateMethod = DarksideStreamerGrpc.getStageBlocksCreateMethod) == null) { + synchronized (DarksideStreamerGrpc.class) { + if ((getStageBlocksCreateMethod = DarksideStreamerGrpc.getStageBlocksCreateMethod) == null) { + DarksideStreamerGrpc.getStageBlocksCreateMethod = getStageBlocksCreateMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "StageBlocksCreate")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.Empty.getDefaultInstance())) + .setSchemaDescriptor(new DarksideStreamerMethodDescriptorSupplier("StageBlocksCreate")) + .build(); + } + } + } + return getStageBlocksCreateMethod; + } + + private static volatile io.grpc.MethodDescriptor getStageTransactionsStreamMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "StageTransactionsStream", + requestType = cash.z.wallet.sdk.rpc.Service.RawTransaction.class, + responseType = cash.z.wallet.sdk.rpc.Service.Empty.class, + methodType = io.grpc.MethodDescriptor.MethodType.CLIENT_STREAMING) + public static io.grpc.MethodDescriptor getStageTransactionsStreamMethod() { + io.grpc.MethodDescriptor getStageTransactionsStreamMethod; + if ((getStageTransactionsStreamMethod = DarksideStreamerGrpc.getStageTransactionsStreamMethod) == null) { + synchronized (DarksideStreamerGrpc.class) { + if ((getStageTransactionsStreamMethod = DarksideStreamerGrpc.getStageTransactionsStreamMethod) == null) { + DarksideStreamerGrpc.getStageTransactionsStreamMethod = getStageTransactionsStreamMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.CLIENT_STREAMING) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "StageTransactionsStream")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.RawTransaction.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.Empty.getDefaultInstance())) + .setSchemaDescriptor(new DarksideStreamerMethodDescriptorSupplier("StageTransactionsStream")) + .build(); + } + } + } + return getStageTransactionsStreamMethod; + } + + private static volatile io.grpc.MethodDescriptor getStageTransactionsMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "StageTransactions", + requestType = cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL.class, + responseType = cash.z.wallet.sdk.rpc.Service.Empty.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getStageTransactionsMethod() { + io.grpc.MethodDescriptor getStageTransactionsMethod; + if ((getStageTransactionsMethod = DarksideStreamerGrpc.getStageTransactionsMethod) == null) { + synchronized (DarksideStreamerGrpc.class) { + if ((getStageTransactionsMethod = DarksideStreamerGrpc.getStageTransactionsMethod) == null) { + DarksideStreamerGrpc.getStageTransactionsMethod = getStageTransactionsMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "StageTransactions")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.Empty.getDefaultInstance())) + .setSchemaDescriptor(new DarksideStreamerMethodDescriptorSupplier("StageTransactions")) + .build(); + } + } + } + return getStageTransactionsMethod; + } + + private static volatile io.grpc.MethodDescriptor getApplyStagedMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "ApplyStaged", + requestType = cash.z.wallet.sdk.rpc.Darkside.DarksideHeight.class, + responseType = cash.z.wallet.sdk.rpc.Service.Empty.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getApplyStagedMethod() { + io.grpc.MethodDescriptor getApplyStagedMethod; + if ((getApplyStagedMethod = DarksideStreamerGrpc.getApplyStagedMethod) == null) { + synchronized (DarksideStreamerGrpc.class) { + if ((getApplyStagedMethod = DarksideStreamerGrpc.getApplyStagedMethod) == null) { + DarksideStreamerGrpc.getApplyStagedMethod = getApplyStagedMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "ApplyStaged")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Darkside.DarksideHeight.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.Empty.getDefaultInstance())) + .setSchemaDescriptor(new DarksideStreamerMethodDescriptorSupplier("ApplyStaged")) + .build(); + } + } + } + return getApplyStagedMethod; + } + + private static volatile io.grpc.MethodDescriptor getGetIncomingTransactionsMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "GetIncomingTransactions", + requestType = cash.z.wallet.sdk.rpc.Service.Empty.class, + responseType = cash.z.wallet.sdk.rpc.Service.RawTransaction.class, + methodType = io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING) + public static io.grpc.MethodDescriptor getGetIncomingTransactionsMethod() { + io.grpc.MethodDescriptor getGetIncomingTransactionsMethod; + if ((getGetIncomingTransactionsMethod = DarksideStreamerGrpc.getGetIncomingTransactionsMethod) == null) { + synchronized (DarksideStreamerGrpc.class) { + if ((getGetIncomingTransactionsMethod = DarksideStreamerGrpc.getGetIncomingTransactionsMethod) == null) { + DarksideStreamerGrpc.getGetIncomingTransactionsMethod = getGetIncomingTransactionsMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetIncomingTransactions")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.Empty.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.RawTransaction.getDefaultInstance())) + .setSchemaDescriptor(new DarksideStreamerMethodDescriptorSupplier("GetIncomingTransactions")) + .build(); + } + } + } + return getGetIncomingTransactionsMethod; + } + + private static volatile io.grpc.MethodDescriptor getClearIncomingTransactionsMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "ClearIncomingTransactions", + requestType = cash.z.wallet.sdk.rpc.Service.Empty.class, + responseType = cash.z.wallet.sdk.rpc.Service.Empty.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getClearIncomingTransactionsMethod() { + io.grpc.MethodDescriptor getClearIncomingTransactionsMethod; + if ((getClearIncomingTransactionsMethod = DarksideStreamerGrpc.getClearIncomingTransactionsMethod) == null) { + synchronized (DarksideStreamerGrpc.class) { + if ((getClearIncomingTransactionsMethod = DarksideStreamerGrpc.getClearIncomingTransactionsMethod) == null) { + DarksideStreamerGrpc.getClearIncomingTransactionsMethod = getClearIncomingTransactionsMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "ClearIncomingTransactions")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.Empty.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + cash.z.wallet.sdk.rpc.Service.Empty.getDefaultInstance())) + .setSchemaDescriptor(new DarksideStreamerMethodDescriptorSupplier("ClearIncomingTransactions")) + .build(); + } + } + } + return getClearIncomingTransactionsMethod; + } + + /** + * Creates a new async stub that supports all call types for the service + */ + public static DarksideStreamerStub newStub(io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public DarksideStreamerStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new DarksideStreamerStub(channel, callOptions); + } + }; + return DarksideStreamerStub.newStub(factory, channel); + } + + /** + * Creates a new blocking-style stub that supports unary and streaming output calls on the service + */ + public static DarksideStreamerBlockingStub newBlockingStub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public DarksideStreamerBlockingStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new DarksideStreamerBlockingStub(channel, callOptions); + } + }; + return DarksideStreamerBlockingStub.newStub(factory, channel); + } + + /** + * Creates a new ListenableFuture-style stub that supports unary calls on the service + */ + public static DarksideStreamerFutureStub newFutureStub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public DarksideStreamerFutureStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new DarksideStreamerFutureStub(channel, callOptions); + } + }; + return DarksideStreamerFutureStub.newStub(factory, channel); + } + + /** + *
+   * Darksidewalletd maintains two staging areas, blocks and transactions. The
+   * Stage*() gRPCs add items to the staging area; ApplyStaged() "applies" everything
+   * in the staging area to the working (operational) state that the mock zcashd
+   * serves; transactions are placed into their corresponding blocks (by height).
+   * 
+ */ + public static abstract class DarksideStreamerImplBase implements io.grpc.BindableService { + + /** + *
+     * Reset reverts all darksidewalletd state (active block range, latest height,
+     * staged blocks and transactions) and lightwalletd state (cache) to empty,
+     * the same as the initial state. This occurs synchronously and instantaneously;
+     * no reorg happens in lightwalletd. This is good to do before each independent
+     * test so that no state leaks from one test to another.
+     * Also sets (some of) the values returned by GetLightdInfo(). The Sapling
+     * activation height specified here must be where the block range starts.
+     * 
+ */ + public void reset(cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getResetMethod(), responseObserver); + } + + /** + *
+     * StageBlocksStream accepts a list of blocks and saves them into the blocks
+     * staging area until ApplyStaged() is called; there is no immediate effect on
+     * the mock zcashd. Blocks are hex-encoded. Order is important, see ApplyStaged.
+     * 
+ */ + public io.grpc.stub.StreamObserver stageBlocksStream( + io.grpc.stub.StreamObserver responseObserver) { + return io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall(getStageBlocksStreamMethod(), responseObserver); + } + + /** + *
+     * StageBlocks is the same as StageBlocksStream() except the blocks are fetched
+     * from the given URL. Blocks are one per line, hex-encoded (not JSON).
+     * 
+ */ + public void stageBlocks(cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getStageBlocksMethod(), responseObserver); + } + + /** + *
+     * StageBlocksCreate is like the previous two, except it creates 'count'
+     * empty blocks at consecutive heights starting at height 'height'. The
+     * 'nonce' is part of the header, so it contributes to the block hash; this
+     * lets you create identical blocks (same transactions and height), but with
+     * different hashes.
+     * 
+ */ + public void stageBlocksCreate(cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getStageBlocksCreateMethod(), responseObserver); + } + + /** + *
+     * StageTransactionsStream stores the given transaction-height pairs in the
+     * staging area until ApplyStaged() is called. Note that these transactions
+     * are not returned by the production GetTransaction() gRPC until they
+     * appear in a "mined" block (contained in the active blockchain presented
+     * by the mock zcashd).
+     * 
+ */ + public io.grpc.stub.StreamObserver stageTransactionsStream( + io.grpc.stub.StreamObserver responseObserver) { + return io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall(getStageTransactionsStreamMethod(), responseObserver); + } + + /** + *
+     * StageTransactions is the same except the transactions are fetched from
+     * the given url. They are all staged into the block at the given height.
+     * Staging transactions to different heights requires multiple calls.
+     * 
+ */ + public void stageTransactions(cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getStageTransactionsMethod(), responseObserver); + } + + /** + *
+     * ApplyStaged iterates the list of blocks that were staged by the
+     * StageBlocks*() gRPCs, in the order they were staged, and "merges" each
+     * into the active, working blocks list that the mock zcashd is presenting
+     * to lightwalletd. Even as each block is applied, the active list can't
+     * have gaps; if the active block range is 1000-1006, and the staged block
+     * range is 1003-1004, the resulting range is 1000-1004, with 1000-1002
+     * unchanged, blocks 1003-1004 from the new range, and 1005-1006 dropped.
+     * After merging all blocks, ApplyStaged() appends staged transactions (in
+     * the order received) into each one's corresponding (by height) block
+     * The staging area is then cleared.
+     * The argument specifies the latest block height that mock zcashd reports
+     * (i.e. what's returned by GetLatestBlock). Note that ApplyStaged() can
+     * also be used to simply advance the latest block height presented by mock
+     * zcashd. That is, there doesn't need to be anything in the staging area.
+     * 
+ */ + public void applyStaged(cash.z.wallet.sdk.rpc.Darkside.DarksideHeight request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getApplyStagedMethod(), responseObserver); + } + + /** + *
+     * Calls to the production gRPC SendTransaction() store the transaction in
+     * a separate area (not the staging area); this method returns all transactions
+     * in this separate area, which is then cleared. The height returned
+     * with each transaction is -1 (invalid) since these transactions haven't
+     * been mined yet. The intention is that the transactions returned here can
+     * then, for example, be given to StageTransactions() to get them "mined"
+     * into a specified block on the next ApplyStaged().
+     * 
+ */ + public void getIncomingTransactions(cash.z.wallet.sdk.rpc.Service.Empty request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetIncomingTransactionsMethod(), responseObserver); + } + + /** + *
+     * Clear the incoming transaction pool.
+     * 
+ */ + public void clearIncomingTransactions(cash.z.wallet.sdk.rpc.Service.Empty request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getClearIncomingTransactionsMethod(), responseObserver); + } + + @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + getResetMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState, + cash.z.wallet.sdk.rpc.Service.Empty>( + this, METHODID_RESET))) + .addMethod( + getStageBlocksStreamMethod(), + io.grpc.stub.ServerCalls.asyncClientStreamingCall( + new MethodHandlers< + cash.z.wallet.sdk.rpc.Darkside.DarksideBlock, + cash.z.wallet.sdk.rpc.Service.Empty>( + this, METHODID_STAGE_BLOCKS_STREAM))) + .addMethod( + getStageBlocksMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL, + cash.z.wallet.sdk.rpc.Service.Empty>( + this, METHODID_STAGE_BLOCKS))) + .addMethod( + getStageBlocksCreateMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks, + cash.z.wallet.sdk.rpc.Service.Empty>( + this, METHODID_STAGE_BLOCKS_CREATE))) + .addMethod( + getStageTransactionsStreamMethod(), + io.grpc.stub.ServerCalls.asyncClientStreamingCall( + new MethodHandlers< + cash.z.wallet.sdk.rpc.Service.RawTransaction, + cash.z.wallet.sdk.rpc.Service.Empty>( + this, METHODID_STAGE_TRANSACTIONS_STREAM))) + .addMethod( + getStageTransactionsMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL, + cash.z.wallet.sdk.rpc.Service.Empty>( + this, METHODID_STAGE_TRANSACTIONS))) + .addMethod( + getApplyStagedMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + cash.z.wallet.sdk.rpc.Darkside.DarksideHeight, + cash.z.wallet.sdk.rpc.Service.Empty>( + this, METHODID_APPLY_STAGED))) + .addMethod( + getGetIncomingTransactionsMethod(), + io.grpc.stub.ServerCalls.asyncServerStreamingCall( + new MethodHandlers< + cash.z.wallet.sdk.rpc.Service.Empty, + cash.z.wallet.sdk.rpc.Service.RawTransaction>( + this, METHODID_GET_INCOMING_TRANSACTIONS))) + .addMethod( + getClearIncomingTransactionsMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + cash.z.wallet.sdk.rpc.Service.Empty, + cash.z.wallet.sdk.rpc.Service.Empty>( + this, METHODID_CLEAR_INCOMING_TRANSACTIONS))) + .build(); + } + } + + /** + *
+   * Darksidewalletd maintains two staging areas, blocks and transactions. The
+   * Stage*() gRPCs add items to the staging area; ApplyStaged() "applies" everything
+   * in the staging area to the working (operational) state that the mock zcashd
+   * serves; transactions are placed into their corresponding blocks (by height).
+   * 
+ */ + public static final class DarksideStreamerStub extends io.grpc.stub.AbstractAsyncStub { + private DarksideStreamerStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected DarksideStreamerStub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new DarksideStreamerStub(channel, callOptions); + } + + /** + *
+     * Reset reverts all darksidewalletd state (active block range, latest height,
+     * staged blocks and transactions) and lightwalletd state (cache) to empty,
+     * the same as the initial state. This occurs synchronously and instantaneously;
+     * no reorg happens in lightwalletd. This is good to do before each independent
+     * test so that no state leaks from one test to another.
+     * Also sets (some of) the values returned by GetLightdInfo(). The Sapling
+     * activation height specified here must be where the block range starts.
+     * 
+ */ + public void reset(cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getResetMethod(), getCallOptions()), request, responseObserver); + } + + /** + *
+     * StageBlocksStream accepts a list of blocks and saves them into the blocks
+     * staging area until ApplyStaged() is called; there is no immediate effect on
+     * the mock zcashd. Blocks are hex-encoded. Order is important, see ApplyStaged.
+     * 
+ */ + public io.grpc.stub.StreamObserver stageBlocksStream( + io.grpc.stub.StreamObserver responseObserver) { + return io.grpc.stub.ClientCalls.asyncClientStreamingCall( + getChannel().newCall(getStageBlocksStreamMethod(), getCallOptions()), responseObserver); + } + + /** + *
+     * StageBlocks is the same as StageBlocksStream() except the blocks are fetched
+     * from the given URL. Blocks are one per line, hex-encoded (not JSON).
+     * 
+ */ + public void stageBlocks(cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getStageBlocksMethod(), getCallOptions()), request, responseObserver); + } + + /** + *
+     * StageBlocksCreate is like the previous two, except it creates 'count'
+     * empty blocks at consecutive heights starting at height 'height'. The
+     * 'nonce' is part of the header, so it contributes to the block hash; this
+     * lets you create identical blocks (same transactions and height), but with
+     * different hashes.
+     * 
+ */ + public void stageBlocksCreate(cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getStageBlocksCreateMethod(), getCallOptions()), request, responseObserver); + } + + /** + *
+     * StageTransactionsStream stores the given transaction-height pairs in the
+     * staging area until ApplyStaged() is called. Note that these transactions
+     * are not returned by the production GetTransaction() gRPC until they
+     * appear in a "mined" block (contained in the active blockchain presented
+     * by the mock zcashd).
+     * 
+ */ + public io.grpc.stub.StreamObserver stageTransactionsStream( + io.grpc.stub.StreamObserver responseObserver) { + return io.grpc.stub.ClientCalls.asyncClientStreamingCall( + getChannel().newCall(getStageTransactionsStreamMethod(), getCallOptions()), responseObserver); + } + + /** + *
+     * StageTransactions is the same except the transactions are fetched from
+     * the given url. They are all staged into the block at the given height.
+     * Staging transactions to different heights requires multiple calls.
+     * 
+ */ + public void stageTransactions(cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getStageTransactionsMethod(), getCallOptions()), request, responseObserver); + } + + /** + *
+     * ApplyStaged iterates the list of blocks that were staged by the
+     * StageBlocks*() gRPCs, in the order they were staged, and "merges" each
+     * into the active, working blocks list that the mock zcashd is presenting
+     * to lightwalletd. Even as each block is applied, the active list can't
+     * have gaps; if the active block range is 1000-1006, and the staged block
+     * range is 1003-1004, the resulting range is 1000-1004, with 1000-1002
+     * unchanged, blocks 1003-1004 from the new range, and 1005-1006 dropped.
+     * After merging all blocks, ApplyStaged() appends staged transactions (in
+     * the order received) into each one's corresponding (by height) block
+     * The staging area is then cleared.
+     * The argument specifies the latest block height that mock zcashd reports
+     * (i.e. what's returned by GetLatestBlock). Note that ApplyStaged() can
+     * also be used to simply advance the latest block height presented by mock
+     * zcashd. That is, there doesn't need to be anything in the staging area.
+     * 
+ */ + public void applyStaged(cash.z.wallet.sdk.rpc.Darkside.DarksideHeight request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getApplyStagedMethod(), getCallOptions()), request, responseObserver); + } + + /** + *
+     * Calls to the production gRPC SendTransaction() store the transaction in
+     * a separate area (not the staging area); this method returns all transactions
+     * in this separate area, which is then cleared. The height returned
+     * with each transaction is -1 (invalid) since these transactions haven't
+     * been mined yet. The intention is that the transactions returned here can
+     * then, for example, be given to StageTransactions() to get them "mined"
+     * into a specified block on the next ApplyStaged().
+     * 
+ */ + public void getIncomingTransactions(cash.z.wallet.sdk.rpc.Service.Empty request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncServerStreamingCall( + getChannel().newCall(getGetIncomingTransactionsMethod(), getCallOptions()), request, responseObserver); + } + + /** + *
+     * Clear the incoming transaction pool.
+     * 
+ */ + public void clearIncomingTransactions(cash.z.wallet.sdk.rpc.Service.Empty request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getClearIncomingTransactionsMethod(), getCallOptions()), request, responseObserver); + } + } + + /** + *
+   * Darksidewalletd maintains two staging areas, blocks and transactions. The
+   * Stage*() gRPCs add items to the staging area; ApplyStaged() "applies" everything
+   * in the staging area to the working (operational) state that the mock zcashd
+   * serves; transactions are placed into their corresponding blocks (by height).
+   * 
+ */ + public static final class DarksideStreamerBlockingStub extends io.grpc.stub.AbstractBlockingStub { + private DarksideStreamerBlockingStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected DarksideStreamerBlockingStub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new DarksideStreamerBlockingStub(channel, callOptions); + } + + /** + *
+     * Reset reverts all darksidewalletd state (active block range, latest height,
+     * staged blocks and transactions) and lightwalletd state (cache) to empty,
+     * the same as the initial state. This occurs synchronously and instantaneously;
+     * no reorg happens in lightwalletd. This is good to do before each independent
+     * test so that no state leaks from one test to another.
+     * Also sets (some of) the values returned by GetLightdInfo(). The Sapling
+     * activation height specified here must be where the block range starts.
+     * 
+ */ + public cash.z.wallet.sdk.rpc.Service.Empty reset(cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getResetMethod(), getCallOptions(), request); + } + + /** + *
+     * StageBlocks is the same as StageBlocksStream() except the blocks are fetched
+     * from the given URL. Blocks are one per line, hex-encoded (not JSON).
+     * 
+ */ + public cash.z.wallet.sdk.rpc.Service.Empty stageBlocks(cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getStageBlocksMethod(), getCallOptions(), request); + } + + /** + *
+     * StageBlocksCreate is like the previous two, except it creates 'count'
+     * empty blocks at consecutive heights starting at height 'height'. The
+     * 'nonce' is part of the header, so it contributes to the block hash; this
+     * lets you create identical blocks (same transactions and height), but with
+     * different hashes.
+     * 
+ */ + public cash.z.wallet.sdk.rpc.Service.Empty stageBlocksCreate(cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getStageBlocksCreateMethod(), getCallOptions(), request); + } + + /** + *
+     * StageTransactions is the same except the transactions are fetched from
+     * the given url. They are all staged into the block at the given height.
+     * Staging transactions to different heights requires multiple calls.
+     * 
+ */ + public cash.z.wallet.sdk.rpc.Service.Empty stageTransactions(cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getStageTransactionsMethod(), getCallOptions(), request); + } + + /** + *
+     * ApplyStaged iterates the list of blocks that were staged by the
+     * StageBlocks*() gRPCs, in the order they were staged, and "merges" each
+     * into the active, working blocks list that the mock zcashd is presenting
+     * to lightwalletd. Even as each block is applied, the active list can't
+     * have gaps; if the active block range is 1000-1006, and the staged block
+     * range is 1003-1004, the resulting range is 1000-1004, with 1000-1002
+     * unchanged, blocks 1003-1004 from the new range, and 1005-1006 dropped.
+     * After merging all blocks, ApplyStaged() appends staged transactions (in
+     * the order received) into each one's corresponding (by height) block
+     * The staging area is then cleared.
+     * The argument specifies the latest block height that mock zcashd reports
+     * (i.e. what's returned by GetLatestBlock). Note that ApplyStaged() can
+     * also be used to simply advance the latest block height presented by mock
+     * zcashd. That is, there doesn't need to be anything in the staging area.
+     * 
+ */ + public cash.z.wallet.sdk.rpc.Service.Empty applyStaged(cash.z.wallet.sdk.rpc.Darkside.DarksideHeight request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getApplyStagedMethod(), getCallOptions(), request); + } + + /** + *
+     * Calls to the production gRPC SendTransaction() store the transaction in
+     * a separate area (not the staging area); this method returns all transactions
+     * in this separate area, which is then cleared. The height returned
+     * with each transaction is -1 (invalid) since these transactions haven't
+     * been mined yet. The intention is that the transactions returned here can
+     * then, for example, be given to StageTransactions() to get them "mined"
+     * into a specified block on the next ApplyStaged().
+     * 
+ */ + public java.util.Iterator getIncomingTransactions( + cash.z.wallet.sdk.rpc.Service.Empty request) { + return io.grpc.stub.ClientCalls.blockingServerStreamingCall( + getChannel(), getGetIncomingTransactionsMethod(), getCallOptions(), request); + } + + /** + *
+     * Clear the incoming transaction pool.
+     * 
+ */ + public cash.z.wallet.sdk.rpc.Service.Empty clearIncomingTransactions(cash.z.wallet.sdk.rpc.Service.Empty request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getClearIncomingTransactionsMethod(), getCallOptions(), request); + } + } + + /** + *
+   * Darksidewalletd maintains two staging areas, blocks and transactions. The
+   * Stage*() gRPCs add items to the staging area; ApplyStaged() "applies" everything
+   * in the staging area to the working (operational) state that the mock zcashd
+   * serves; transactions are placed into their corresponding blocks (by height).
+   * 
+ */ + public static final class DarksideStreamerFutureStub extends io.grpc.stub.AbstractFutureStub { + private DarksideStreamerFutureStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected DarksideStreamerFutureStub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new DarksideStreamerFutureStub(channel, callOptions); + } + + /** + *
+     * Reset reverts all darksidewalletd state (active block range, latest height,
+     * staged blocks and transactions) and lightwalletd state (cache) to empty,
+     * the same as the initial state. This occurs synchronously and instantaneously;
+     * no reorg happens in lightwalletd. This is good to do before each independent
+     * test so that no state leaks from one test to another.
+     * Also sets (some of) the values returned by GetLightdInfo(). The Sapling
+     * activation height specified here must be where the block range starts.
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture reset( + cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getResetMethod(), getCallOptions()), request); + } + + /** + *
+     * StageBlocks is the same as StageBlocksStream() except the blocks are fetched
+     * from the given URL. Blocks are one per line, hex-encoded (not JSON).
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture stageBlocks( + cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getStageBlocksMethod(), getCallOptions()), request); + } + + /** + *
+     * StageBlocksCreate is like the previous two, except it creates 'count'
+     * empty blocks at consecutive heights starting at height 'height'. The
+     * 'nonce' is part of the header, so it contributes to the block hash; this
+     * lets you create identical blocks (same transactions and height), but with
+     * different hashes.
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture stageBlocksCreate( + cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getStageBlocksCreateMethod(), getCallOptions()), request); + } + + /** + *
+     * StageTransactions is the same except the transactions are fetched from
+     * the given url. They are all staged into the block at the given height.
+     * Staging transactions to different heights requires multiple calls.
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture stageTransactions( + cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getStageTransactionsMethod(), getCallOptions()), request); + } + + /** + *
+     * ApplyStaged iterates the list of blocks that were staged by the
+     * StageBlocks*() gRPCs, in the order they were staged, and "merges" each
+     * into the active, working blocks list that the mock zcashd is presenting
+     * to lightwalletd. Even as each block is applied, the active list can't
+     * have gaps; if the active block range is 1000-1006, and the staged block
+     * range is 1003-1004, the resulting range is 1000-1004, with 1000-1002
+     * unchanged, blocks 1003-1004 from the new range, and 1005-1006 dropped.
+     * After merging all blocks, ApplyStaged() appends staged transactions (in
+     * the order received) into each one's corresponding (by height) block
+     * The staging area is then cleared.
+     * The argument specifies the latest block height that mock zcashd reports
+     * (i.e. what's returned by GetLatestBlock). Note that ApplyStaged() can
+     * also be used to simply advance the latest block height presented by mock
+     * zcashd. That is, there doesn't need to be anything in the staging area.
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture applyStaged( + cash.z.wallet.sdk.rpc.Darkside.DarksideHeight request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getApplyStagedMethod(), getCallOptions()), request); + } + + /** + *
+     * Clear the incoming transaction pool.
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture clearIncomingTransactions( + cash.z.wallet.sdk.rpc.Service.Empty request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getClearIncomingTransactionsMethod(), getCallOptions()), request); + } + } + + private static final int METHODID_RESET = 0; + private static final int METHODID_STAGE_BLOCKS = 1; + private static final int METHODID_STAGE_BLOCKS_CREATE = 2; + private static final int METHODID_STAGE_TRANSACTIONS = 3; + private static final int METHODID_APPLY_STAGED = 4; + private static final int METHODID_GET_INCOMING_TRANSACTIONS = 5; + private static final int METHODID_CLEAR_INCOMING_TRANSACTIONS = 6; + private static final int METHODID_STAGE_BLOCKS_STREAM = 7; + private static final int METHODID_STAGE_TRANSACTIONS_STREAM = 8; + + private static final class MethodHandlers implements + io.grpc.stub.ServerCalls.UnaryMethod, + io.grpc.stub.ServerCalls.ServerStreamingMethod, + io.grpc.stub.ServerCalls.ClientStreamingMethod, + io.grpc.stub.ServerCalls.BidiStreamingMethod { + private final DarksideStreamerImplBase serviceImpl; + private final int methodId; + + MethodHandlers(DarksideStreamerImplBase serviceImpl, int methodId) { + this.serviceImpl = serviceImpl; + this.methodId = methodId; + } + + @java.lang.Override + @java.lang.SuppressWarnings("unchecked") + public void invoke(Req request, io.grpc.stub.StreamObserver responseObserver) { + switch (methodId) { + case METHODID_RESET: + serviceImpl.reset((cash.z.wallet.sdk.rpc.Darkside.DarksideMetaState) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_STAGE_BLOCKS: + serviceImpl.stageBlocks((cash.z.wallet.sdk.rpc.Darkside.DarksideBlocksURL) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_STAGE_BLOCKS_CREATE: + serviceImpl.stageBlocksCreate((cash.z.wallet.sdk.rpc.Darkside.DarksideEmptyBlocks) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_STAGE_TRANSACTIONS: + serviceImpl.stageTransactions((cash.z.wallet.sdk.rpc.Darkside.DarksideTransactionsURL) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_APPLY_STAGED: + serviceImpl.applyStaged((cash.z.wallet.sdk.rpc.Darkside.DarksideHeight) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_GET_INCOMING_TRANSACTIONS: + serviceImpl.getIncomingTransactions((cash.z.wallet.sdk.rpc.Service.Empty) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_CLEAR_INCOMING_TRANSACTIONS: + serviceImpl.clearIncomingTransactions((cash.z.wallet.sdk.rpc.Service.Empty) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + default: + throw new AssertionError(); + } + } + + @java.lang.Override + @java.lang.SuppressWarnings("unchecked") + public io.grpc.stub.StreamObserver invoke( + io.grpc.stub.StreamObserver responseObserver) { + switch (methodId) { + case METHODID_STAGE_BLOCKS_STREAM: + return (io.grpc.stub.StreamObserver) serviceImpl.stageBlocksStream( + (io.grpc.stub.StreamObserver) responseObserver); + case METHODID_STAGE_TRANSACTIONS_STREAM: + return (io.grpc.stub.StreamObserver) serviceImpl.stageTransactionsStream( + (io.grpc.stub.StreamObserver) responseObserver); + default: + throw new AssertionError(); + } + } + } + + private static abstract class DarksideStreamerBaseDescriptorSupplier + implements io.grpc.protobuf.ProtoFileDescriptorSupplier, io.grpc.protobuf.ProtoServiceDescriptorSupplier { + DarksideStreamerBaseDescriptorSupplier() {} + + @java.lang.Override + public com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() { + return cash.z.wallet.sdk.rpc.Darkside.getDescriptor(); + } + + @java.lang.Override + public com.google.protobuf.Descriptors.ServiceDescriptor getServiceDescriptor() { + return getFileDescriptor().findServiceByName("DarksideStreamer"); + } + } + + private static final class DarksideStreamerFileDescriptorSupplier + extends DarksideStreamerBaseDescriptorSupplier { + DarksideStreamerFileDescriptorSupplier() {} + } + + private static final class DarksideStreamerMethodDescriptorSupplier + extends DarksideStreamerBaseDescriptorSupplier + implements io.grpc.protobuf.ProtoMethodDescriptorSupplier { + private final String methodName; + + DarksideStreamerMethodDescriptorSupplier(String methodName) { + this.methodName = methodName; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.MethodDescriptor getMethodDescriptor() { + return getServiceDescriptor().findMethodByName(methodName); + } + } + + private static volatile io.grpc.ServiceDescriptor serviceDescriptor; + + public static io.grpc.ServiceDescriptor getServiceDescriptor() { + io.grpc.ServiceDescriptor result = serviceDescriptor; + if (result == null) { + synchronized (DarksideStreamerGrpc.class) { + result = serviceDescriptor; + if (result == null) { + serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME) + .setSchemaDescriptor(new DarksideStreamerFileDescriptorSupplier()) + .addMethod(getResetMethod()) + .addMethod(getStageBlocksStreamMethod()) + .addMethod(getStageBlocksMethod()) + .addMethod(getStageBlocksCreateMethod()) + .addMethod(getStageTransactionsStreamMethod()) + .addMethod(getStageTransactionsMethod()) + .addMethod(getApplyStagedMethod()) + .addMethod(getGetIncomingTransactionsMethod()) + .addMethod(getClearIncomingTransactionsMethod()) + .build(); + } + } + } + return result; + } +} diff --git a/src/main/java/cash/z/wallet/sdk/rpc/Service.java b/src/main/java/cash/z/wallet/sdk/rpc/Service.java new file mode 100644 index 00000000..3ffc0247 --- /dev/null +++ b/src/main/java/cash/z/wallet/sdk/rpc/Service.java @@ -0,0 +1,15106 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: service.proto + +package cash.z.wallet.sdk.rpc; + +public final class Service { + private Service() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistryLite registry) { + } + + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + registerAllExtensions( + (com.google.protobuf.ExtensionRegistryLite) registry); + } + public interface BlockIDOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.BlockID) + com.google.protobuf.MessageOrBuilder { + + /** + * uint64 height = 1; + * @return The height. + */ + long getHeight(); + + /** + * bytes hash = 2; + * @return The hash. + */ + com.google.protobuf.ByteString getHash(); + } + /** + *
+   * A BlockID message contains identifiers to select a block: a height or a
+   * hash. Specification by hash is not implemented, but may be in the future.
+   * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.BlockID} + */ + public static final class BlockID extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.BlockID) + BlockIDOrBuilder { + private static final long serialVersionUID = 0L; + // Use BlockID.newBuilder() to construct. + private BlockID(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private BlockID() { + hash_ = com.google.protobuf.ByteString.EMPTY; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new BlockID(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private BlockID( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: { + + height_ = input.readUInt64(); + break; + } + case 18: { + + hash_ = input.readBytes(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_BlockID_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_BlockID_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.BlockID.class, cash.z.wallet.sdk.rpc.Service.BlockID.Builder.class); + } + + public static final int HEIGHT_FIELD_NUMBER = 1; + private long height_; + /** + * uint64 height = 1; + * @return The height. + */ + @java.lang.Override + public long getHeight() { + return height_; + } + + public static final int HASH_FIELD_NUMBER = 2; + private com.google.protobuf.ByteString hash_; + /** + * bytes hash = 2; + * @return The hash. + */ + @java.lang.Override + public com.google.protobuf.ByteString getHash() { + return hash_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (height_ != 0L) { + output.writeUInt64(1, height_); + } + if (!hash_.isEmpty()) { + output.writeBytes(2, hash_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (height_ != 0L) { + size += com.google.protobuf.CodedOutputStream + .computeUInt64Size(1, height_); + } + if (!hash_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, hash_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.Service.BlockID)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.Service.BlockID other = (cash.z.wallet.sdk.rpc.Service.BlockID) obj; + + if (getHeight() + != other.getHeight()) return false; + if (!getHash() + .equals(other.getHash())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + HEIGHT_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashLong( + getHeight()); + hash = (37 * hash) + HASH_FIELD_NUMBER; + hash = (53 * hash) + getHash().hashCode(); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.Service.BlockID parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.BlockID parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.BlockID parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.BlockID parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.BlockID parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.BlockID parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.BlockID parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.BlockID parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.BlockID parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.BlockID parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.BlockID parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.BlockID parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.Service.BlockID prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * A BlockID message contains identifiers to select a block: a height or a
+     * hash. Specification by hash is not implemented, but may be in the future.
+     * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.BlockID} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.BlockID) + cash.z.wallet.sdk.rpc.Service.BlockIDOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_BlockID_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_BlockID_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.BlockID.class, cash.z.wallet.sdk.rpc.Service.BlockID.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.Service.BlockID.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + height_ = 0L; + + hash_ = com.google.protobuf.ByteString.EMPTY; + + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_BlockID_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.BlockID getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.Service.BlockID.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.BlockID build() { + cash.z.wallet.sdk.rpc.Service.BlockID result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.BlockID buildPartial() { + cash.z.wallet.sdk.rpc.Service.BlockID result = new cash.z.wallet.sdk.rpc.Service.BlockID(this); + result.height_ = height_; + result.hash_ = hash_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.Service.BlockID) { + return mergeFrom((cash.z.wallet.sdk.rpc.Service.BlockID)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.Service.BlockID other) { + if (other == cash.z.wallet.sdk.rpc.Service.BlockID.getDefaultInstance()) return this; + if (other.getHeight() != 0L) { + setHeight(other.getHeight()); + } + if (other.getHash() != com.google.protobuf.ByteString.EMPTY) { + setHash(other.getHash()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.Service.BlockID parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.Service.BlockID) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private long height_ ; + /** + * uint64 height = 1; + * @return The height. + */ + @java.lang.Override + public long getHeight() { + return height_; + } + /** + * uint64 height = 1; + * @param value The height to set. + * @return This builder for chaining. + */ + public Builder setHeight(long value) { + + height_ = value; + onChanged(); + return this; + } + /** + * uint64 height = 1; + * @return This builder for chaining. + */ + public Builder clearHeight() { + + height_ = 0L; + onChanged(); + return this; + } + + private com.google.protobuf.ByteString hash_ = com.google.protobuf.ByteString.EMPTY; + /** + * bytes hash = 2; + * @return The hash. + */ + @java.lang.Override + public com.google.protobuf.ByteString getHash() { + return hash_; + } + /** + * bytes hash = 2; + * @param value The hash to set. + * @return This builder for chaining. + */ + public Builder setHash(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + + hash_ = value; + onChanged(); + return this; + } + /** + * bytes hash = 2; + * @return This builder for chaining. + */ + public Builder clearHash() { + + hash_ = getDefaultInstance().getHash(); + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.BlockID) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.BlockID) + private static final cash.z.wallet.sdk.rpc.Service.BlockID DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.Service.BlockID(); + } + + public static cash.z.wallet.sdk.rpc.Service.BlockID getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public BlockID parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new BlockID(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.BlockID getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface BlockRangeOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.BlockRange) + com.google.protobuf.MessageOrBuilder { + + /** + * .cash.z.wallet.sdk.rpc.BlockID start = 1; + * @return Whether the start field is set. + */ + boolean hasStart(); + /** + * .cash.z.wallet.sdk.rpc.BlockID start = 1; + * @return The start. + */ + cash.z.wallet.sdk.rpc.Service.BlockID getStart(); + /** + * .cash.z.wallet.sdk.rpc.BlockID start = 1; + */ + cash.z.wallet.sdk.rpc.Service.BlockIDOrBuilder getStartOrBuilder(); + + /** + * .cash.z.wallet.sdk.rpc.BlockID end = 2; + * @return Whether the end field is set. + */ + boolean hasEnd(); + /** + * .cash.z.wallet.sdk.rpc.BlockID end = 2; + * @return The end. + */ + cash.z.wallet.sdk.rpc.Service.BlockID getEnd(); + /** + * .cash.z.wallet.sdk.rpc.BlockID end = 2; + */ + cash.z.wallet.sdk.rpc.Service.BlockIDOrBuilder getEndOrBuilder(); + } + /** + *
+   * BlockRange specifies a series of blocks from start to end inclusive.
+   * Both BlockIDs must be heights; specification by hash is not yet supported.
+   * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.BlockRange} + */ + public static final class BlockRange extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.BlockRange) + BlockRangeOrBuilder { + private static final long serialVersionUID = 0L; + // Use BlockRange.newBuilder() to construct. + private BlockRange(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private BlockRange() { + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new BlockRange(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private BlockRange( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + cash.z.wallet.sdk.rpc.Service.BlockID.Builder subBuilder = null; + if (start_ != null) { + subBuilder = start_.toBuilder(); + } + start_ = input.readMessage(cash.z.wallet.sdk.rpc.Service.BlockID.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(start_); + start_ = subBuilder.buildPartial(); + } + + break; + } + case 18: { + cash.z.wallet.sdk.rpc.Service.BlockID.Builder subBuilder = null; + if (end_ != null) { + subBuilder = end_.toBuilder(); + } + end_ = input.readMessage(cash.z.wallet.sdk.rpc.Service.BlockID.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(end_); + end_ = subBuilder.buildPartial(); + } + + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_BlockRange_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_BlockRange_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.BlockRange.class, cash.z.wallet.sdk.rpc.Service.BlockRange.Builder.class); + } + + public static final int START_FIELD_NUMBER = 1; + private cash.z.wallet.sdk.rpc.Service.BlockID start_; + /** + * .cash.z.wallet.sdk.rpc.BlockID start = 1; + * @return Whether the start field is set. + */ + @java.lang.Override + public boolean hasStart() { + return start_ != null; + } + /** + * .cash.z.wallet.sdk.rpc.BlockID start = 1; + * @return The start. + */ + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.BlockID getStart() { + return start_ == null ? cash.z.wallet.sdk.rpc.Service.BlockID.getDefaultInstance() : start_; + } + /** + * .cash.z.wallet.sdk.rpc.BlockID start = 1; + */ + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.BlockIDOrBuilder getStartOrBuilder() { + return getStart(); + } + + public static final int END_FIELD_NUMBER = 2; + private cash.z.wallet.sdk.rpc.Service.BlockID end_; + /** + * .cash.z.wallet.sdk.rpc.BlockID end = 2; + * @return Whether the end field is set. + */ + @java.lang.Override + public boolean hasEnd() { + return end_ != null; + } + /** + * .cash.z.wallet.sdk.rpc.BlockID end = 2; + * @return The end. + */ + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.BlockID getEnd() { + return end_ == null ? cash.z.wallet.sdk.rpc.Service.BlockID.getDefaultInstance() : end_; + } + /** + * .cash.z.wallet.sdk.rpc.BlockID end = 2; + */ + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.BlockIDOrBuilder getEndOrBuilder() { + return getEnd(); + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (start_ != null) { + output.writeMessage(1, getStart()); + } + if (end_ != null) { + output.writeMessage(2, getEnd()); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (start_ != null) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, getStart()); + } + if (end_ != null) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, getEnd()); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.Service.BlockRange)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.Service.BlockRange other = (cash.z.wallet.sdk.rpc.Service.BlockRange) obj; + + if (hasStart() != other.hasStart()) return false; + if (hasStart()) { + if (!getStart() + .equals(other.getStart())) return false; + } + if (hasEnd() != other.hasEnd()) return false; + if (hasEnd()) { + if (!getEnd() + .equals(other.getEnd())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasStart()) { + hash = (37 * hash) + START_FIELD_NUMBER; + hash = (53 * hash) + getStart().hashCode(); + } + if (hasEnd()) { + hash = (37 * hash) + END_FIELD_NUMBER; + hash = (53 * hash) + getEnd().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.Service.BlockRange parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.BlockRange parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.BlockRange parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.BlockRange parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.BlockRange parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.BlockRange parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.BlockRange parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.BlockRange parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.BlockRange parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.BlockRange parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.BlockRange parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.BlockRange parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.Service.BlockRange prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * BlockRange specifies a series of blocks from start to end inclusive.
+     * Both BlockIDs must be heights; specification by hash is not yet supported.
+     * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.BlockRange} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.BlockRange) + cash.z.wallet.sdk.rpc.Service.BlockRangeOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_BlockRange_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_BlockRange_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.BlockRange.class, cash.z.wallet.sdk.rpc.Service.BlockRange.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.Service.BlockRange.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + if (startBuilder_ == null) { + start_ = null; + } else { + start_ = null; + startBuilder_ = null; + } + if (endBuilder_ == null) { + end_ = null; + } else { + end_ = null; + endBuilder_ = null; + } + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_BlockRange_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.BlockRange getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.Service.BlockRange.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.BlockRange build() { + cash.z.wallet.sdk.rpc.Service.BlockRange result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.BlockRange buildPartial() { + cash.z.wallet.sdk.rpc.Service.BlockRange result = new cash.z.wallet.sdk.rpc.Service.BlockRange(this); + if (startBuilder_ == null) { + result.start_ = start_; + } else { + result.start_ = startBuilder_.build(); + } + if (endBuilder_ == null) { + result.end_ = end_; + } else { + result.end_ = endBuilder_.build(); + } + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.Service.BlockRange) { + return mergeFrom((cash.z.wallet.sdk.rpc.Service.BlockRange)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.Service.BlockRange other) { + if (other == cash.z.wallet.sdk.rpc.Service.BlockRange.getDefaultInstance()) return this; + if (other.hasStart()) { + mergeStart(other.getStart()); + } + if (other.hasEnd()) { + mergeEnd(other.getEnd()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.Service.BlockRange parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.Service.BlockRange) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private cash.z.wallet.sdk.rpc.Service.BlockID start_; + private com.google.protobuf.SingleFieldBuilderV3< + cash.z.wallet.sdk.rpc.Service.BlockID, cash.z.wallet.sdk.rpc.Service.BlockID.Builder, cash.z.wallet.sdk.rpc.Service.BlockIDOrBuilder> startBuilder_; + /** + * .cash.z.wallet.sdk.rpc.BlockID start = 1; + * @return Whether the start field is set. + */ + public boolean hasStart() { + return startBuilder_ != null || start_ != null; + } + /** + * .cash.z.wallet.sdk.rpc.BlockID start = 1; + * @return The start. + */ + public cash.z.wallet.sdk.rpc.Service.BlockID getStart() { + if (startBuilder_ == null) { + return start_ == null ? cash.z.wallet.sdk.rpc.Service.BlockID.getDefaultInstance() : start_; + } else { + return startBuilder_.getMessage(); + } + } + /** + * .cash.z.wallet.sdk.rpc.BlockID start = 1; + */ + public Builder setStart(cash.z.wallet.sdk.rpc.Service.BlockID value) { + if (startBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + start_ = value; + onChanged(); + } else { + startBuilder_.setMessage(value); + } + + return this; + } + /** + * .cash.z.wallet.sdk.rpc.BlockID start = 1; + */ + public Builder setStart( + cash.z.wallet.sdk.rpc.Service.BlockID.Builder builderForValue) { + if (startBuilder_ == null) { + start_ = builderForValue.build(); + onChanged(); + } else { + startBuilder_.setMessage(builderForValue.build()); + } + + return this; + } + /** + * .cash.z.wallet.sdk.rpc.BlockID start = 1; + */ + public Builder mergeStart(cash.z.wallet.sdk.rpc.Service.BlockID value) { + if (startBuilder_ == null) { + if (start_ != null) { + start_ = + cash.z.wallet.sdk.rpc.Service.BlockID.newBuilder(start_).mergeFrom(value).buildPartial(); + } else { + start_ = value; + } + onChanged(); + } else { + startBuilder_.mergeFrom(value); + } + + return this; + } + /** + * .cash.z.wallet.sdk.rpc.BlockID start = 1; + */ + public Builder clearStart() { + if (startBuilder_ == null) { + start_ = null; + onChanged(); + } else { + start_ = null; + startBuilder_ = null; + } + + return this; + } + /** + * .cash.z.wallet.sdk.rpc.BlockID start = 1; + */ + public cash.z.wallet.sdk.rpc.Service.BlockID.Builder getStartBuilder() { + + onChanged(); + return getStartFieldBuilder().getBuilder(); + } + /** + * .cash.z.wallet.sdk.rpc.BlockID start = 1; + */ + public cash.z.wallet.sdk.rpc.Service.BlockIDOrBuilder getStartOrBuilder() { + if (startBuilder_ != null) { + return startBuilder_.getMessageOrBuilder(); + } else { + return start_ == null ? + cash.z.wallet.sdk.rpc.Service.BlockID.getDefaultInstance() : start_; + } + } + /** + * .cash.z.wallet.sdk.rpc.BlockID start = 1; + */ + private com.google.protobuf.SingleFieldBuilderV3< + cash.z.wallet.sdk.rpc.Service.BlockID, cash.z.wallet.sdk.rpc.Service.BlockID.Builder, cash.z.wallet.sdk.rpc.Service.BlockIDOrBuilder> + getStartFieldBuilder() { + if (startBuilder_ == null) { + startBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + cash.z.wallet.sdk.rpc.Service.BlockID, cash.z.wallet.sdk.rpc.Service.BlockID.Builder, cash.z.wallet.sdk.rpc.Service.BlockIDOrBuilder>( + getStart(), + getParentForChildren(), + isClean()); + start_ = null; + } + return startBuilder_; + } + + private cash.z.wallet.sdk.rpc.Service.BlockID end_; + private com.google.protobuf.SingleFieldBuilderV3< + cash.z.wallet.sdk.rpc.Service.BlockID, cash.z.wallet.sdk.rpc.Service.BlockID.Builder, cash.z.wallet.sdk.rpc.Service.BlockIDOrBuilder> endBuilder_; + /** + * .cash.z.wallet.sdk.rpc.BlockID end = 2; + * @return Whether the end field is set. + */ + public boolean hasEnd() { + return endBuilder_ != null || end_ != null; + } + /** + * .cash.z.wallet.sdk.rpc.BlockID end = 2; + * @return The end. + */ + public cash.z.wallet.sdk.rpc.Service.BlockID getEnd() { + if (endBuilder_ == null) { + return end_ == null ? cash.z.wallet.sdk.rpc.Service.BlockID.getDefaultInstance() : end_; + } else { + return endBuilder_.getMessage(); + } + } + /** + * .cash.z.wallet.sdk.rpc.BlockID end = 2; + */ + public Builder setEnd(cash.z.wallet.sdk.rpc.Service.BlockID value) { + if (endBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + end_ = value; + onChanged(); + } else { + endBuilder_.setMessage(value); + } + + return this; + } + /** + * .cash.z.wallet.sdk.rpc.BlockID end = 2; + */ + public Builder setEnd( + cash.z.wallet.sdk.rpc.Service.BlockID.Builder builderForValue) { + if (endBuilder_ == null) { + end_ = builderForValue.build(); + onChanged(); + } else { + endBuilder_.setMessage(builderForValue.build()); + } + + return this; + } + /** + * .cash.z.wallet.sdk.rpc.BlockID end = 2; + */ + public Builder mergeEnd(cash.z.wallet.sdk.rpc.Service.BlockID value) { + if (endBuilder_ == null) { + if (end_ != null) { + end_ = + cash.z.wallet.sdk.rpc.Service.BlockID.newBuilder(end_).mergeFrom(value).buildPartial(); + } else { + end_ = value; + } + onChanged(); + } else { + endBuilder_.mergeFrom(value); + } + + return this; + } + /** + * .cash.z.wallet.sdk.rpc.BlockID end = 2; + */ + public Builder clearEnd() { + if (endBuilder_ == null) { + end_ = null; + onChanged(); + } else { + end_ = null; + endBuilder_ = null; + } + + return this; + } + /** + * .cash.z.wallet.sdk.rpc.BlockID end = 2; + */ + public cash.z.wallet.sdk.rpc.Service.BlockID.Builder getEndBuilder() { + + onChanged(); + return getEndFieldBuilder().getBuilder(); + } + /** + * .cash.z.wallet.sdk.rpc.BlockID end = 2; + */ + public cash.z.wallet.sdk.rpc.Service.BlockIDOrBuilder getEndOrBuilder() { + if (endBuilder_ != null) { + return endBuilder_.getMessageOrBuilder(); + } else { + return end_ == null ? + cash.z.wallet.sdk.rpc.Service.BlockID.getDefaultInstance() : end_; + } + } + /** + * .cash.z.wallet.sdk.rpc.BlockID end = 2; + */ + private com.google.protobuf.SingleFieldBuilderV3< + cash.z.wallet.sdk.rpc.Service.BlockID, cash.z.wallet.sdk.rpc.Service.BlockID.Builder, cash.z.wallet.sdk.rpc.Service.BlockIDOrBuilder> + getEndFieldBuilder() { + if (endBuilder_ == null) { + endBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + cash.z.wallet.sdk.rpc.Service.BlockID, cash.z.wallet.sdk.rpc.Service.BlockID.Builder, cash.z.wallet.sdk.rpc.Service.BlockIDOrBuilder>( + getEnd(), + getParentForChildren(), + isClean()); + end_ = null; + } + return endBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.BlockRange) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.BlockRange) + private static final cash.z.wallet.sdk.rpc.Service.BlockRange DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.Service.BlockRange(); + } + + public static cash.z.wallet.sdk.rpc.Service.BlockRange getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public BlockRange parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new BlockRange(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.BlockRange getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface TxFilterOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.TxFilter) + com.google.protobuf.MessageOrBuilder { + + /** + *
+     * block identifier, height or hash
+     * 
+ * + * .cash.z.wallet.sdk.rpc.BlockID block = 1; + * @return Whether the block field is set. + */ + boolean hasBlock(); + /** + *
+     * block identifier, height or hash
+     * 
+ * + * .cash.z.wallet.sdk.rpc.BlockID block = 1; + * @return The block. + */ + cash.z.wallet.sdk.rpc.Service.BlockID getBlock(); + /** + *
+     * block identifier, height or hash
+     * 
+ * + * .cash.z.wallet.sdk.rpc.BlockID block = 1; + */ + cash.z.wallet.sdk.rpc.Service.BlockIDOrBuilder getBlockOrBuilder(); + + /** + *
+     * index within the block
+     * 
+ * + * uint64 index = 2; + * @return The index. + */ + long getIndex(); + + /** + *
+     * transaction ID (hash, txid)
+     * 
+ * + * bytes hash = 3; + * @return The hash. + */ + com.google.protobuf.ByteString getHash(); + } + /** + *
+   * A TxFilter contains the information needed to identify a particular
+   * transaction: either a block and an index, or a direct transaction hash.
+   * Currently, only specification by hash is supported.
+   * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.TxFilter} + */ + public static final class TxFilter extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.TxFilter) + TxFilterOrBuilder { + private static final long serialVersionUID = 0L; + // Use TxFilter.newBuilder() to construct. + private TxFilter(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private TxFilter() { + hash_ = com.google.protobuf.ByteString.EMPTY; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new TxFilter(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private TxFilter( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + cash.z.wallet.sdk.rpc.Service.BlockID.Builder subBuilder = null; + if (block_ != null) { + subBuilder = block_.toBuilder(); + } + block_ = input.readMessage(cash.z.wallet.sdk.rpc.Service.BlockID.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(block_); + block_ = subBuilder.buildPartial(); + } + + break; + } + case 16: { + + index_ = input.readUInt64(); + break; + } + case 26: { + + hash_ = input.readBytes(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_TxFilter_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_TxFilter_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.TxFilter.class, cash.z.wallet.sdk.rpc.Service.TxFilter.Builder.class); + } + + public static final int BLOCK_FIELD_NUMBER = 1; + private cash.z.wallet.sdk.rpc.Service.BlockID block_; + /** + *
+     * block identifier, height or hash
+     * 
+ * + * .cash.z.wallet.sdk.rpc.BlockID block = 1; + * @return Whether the block field is set. + */ + @java.lang.Override + public boolean hasBlock() { + return block_ != null; + } + /** + *
+     * block identifier, height or hash
+     * 
+ * + * .cash.z.wallet.sdk.rpc.BlockID block = 1; + * @return The block. + */ + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.BlockID getBlock() { + return block_ == null ? cash.z.wallet.sdk.rpc.Service.BlockID.getDefaultInstance() : block_; + } + /** + *
+     * block identifier, height or hash
+     * 
+ * + * .cash.z.wallet.sdk.rpc.BlockID block = 1; + */ + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.BlockIDOrBuilder getBlockOrBuilder() { + return getBlock(); + } + + public static final int INDEX_FIELD_NUMBER = 2; + private long index_; + /** + *
+     * index within the block
+     * 
+ * + * uint64 index = 2; + * @return The index. + */ + @java.lang.Override + public long getIndex() { + return index_; + } + + public static final int HASH_FIELD_NUMBER = 3; + private com.google.protobuf.ByteString hash_; + /** + *
+     * transaction ID (hash, txid)
+     * 
+ * + * bytes hash = 3; + * @return The hash. + */ + @java.lang.Override + public com.google.protobuf.ByteString getHash() { + return hash_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (block_ != null) { + output.writeMessage(1, getBlock()); + } + if (index_ != 0L) { + output.writeUInt64(2, index_); + } + if (!hash_.isEmpty()) { + output.writeBytes(3, hash_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (block_ != null) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, getBlock()); + } + if (index_ != 0L) { + size += com.google.protobuf.CodedOutputStream + .computeUInt64Size(2, index_); + } + if (!hash_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, hash_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.Service.TxFilter)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.Service.TxFilter other = (cash.z.wallet.sdk.rpc.Service.TxFilter) obj; + + if (hasBlock() != other.hasBlock()) return false; + if (hasBlock()) { + if (!getBlock() + .equals(other.getBlock())) return false; + } + if (getIndex() + != other.getIndex()) return false; + if (!getHash() + .equals(other.getHash())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (hasBlock()) { + hash = (37 * hash) + BLOCK_FIELD_NUMBER; + hash = (53 * hash) + getBlock().hashCode(); + } + hash = (37 * hash) + INDEX_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashLong( + getIndex()); + hash = (37 * hash) + HASH_FIELD_NUMBER; + hash = (53 * hash) + getHash().hashCode(); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.Service.TxFilter parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.TxFilter parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.TxFilter parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.TxFilter parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.TxFilter parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.TxFilter parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.TxFilter parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.TxFilter parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.TxFilter parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.TxFilter parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.TxFilter parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.TxFilter parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.Service.TxFilter prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * A TxFilter contains the information needed to identify a particular
+     * transaction: either a block and an index, or a direct transaction hash.
+     * Currently, only specification by hash is supported.
+     * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.TxFilter} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.TxFilter) + cash.z.wallet.sdk.rpc.Service.TxFilterOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_TxFilter_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_TxFilter_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.TxFilter.class, cash.z.wallet.sdk.rpc.Service.TxFilter.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.Service.TxFilter.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + if (blockBuilder_ == null) { + block_ = null; + } else { + block_ = null; + blockBuilder_ = null; + } + index_ = 0L; + + hash_ = com.google.protobuf.ByteString.EMPTY; + + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_TxFilter_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.TxFilter getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.Service.TxFilter.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.TxFilter build() { + cash.z.wallet.sdk.rpc.Service.TxFilter result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.TxFilter buildPartial() { + cash.z.wallet.sdk.rpc.Service.TxFilter result = new cash.z.wallet.sdk.rpc.Service.TxFilter(this); + if (blockBuilder_ == null) { + result.block_ = block_; + } else { + result.block_ = blockBuilder_.build(); + } + result.index_ = index_; + result.hash_ = hash_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.Service.TxFilter) { + return mergeFrom((cash.z.wallet.sdk.rpc.Service.TxFilter)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.Service.TxFilter other) { + if (other == cash.z.wallet.sdk.rpc.Service.TxFilter.getDefaultInstance()) return this; + if (other.hasBlock()) { + mergeBlock(other.getBlock()); + } + if (other.getIndex() != 0L) { + setIndex(other.getIndex()); + } + if (other.getHash() != com.google.protobuf.ByteString.EMPTY) { + setHash(other.getHash()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.Service.TxFilter parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.Service.TxFilter) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private cash.z.wallet.sdk.rpc.Service.BlockID block_; + private com.google.protobuf.SingleFieldBuilderV3< + cash.z.wallet.sdk.rpc.Service.BlockID, cash.z.wallet.sdk.rpc.Service.BlockID.Builder, cash.z.wallet.sdk.rpc.Service.BlockIDOrBuilder> blockBuilder_; + /** + *
+       * block identifier, height or hash
+       * 
+ * + * .cash.z.wallet.sdk.rpc.BlockID block = 1; + * @return Whether the block field is set. + */ + public boolean hasBlock() { + return blockBuilder_ != null || block_ != null; + } + /** + *
+       * block identifier, height or hash
+       * 
+ * + * .cash.z.wallet.sdk.rpc.BlockID block = 1; + * @return The block. + */ + public cash.z.wallet.sdk.rpc.Service.BlockID getBlock() { + if (blockBuilder_ == null) { + return block_ == null ? cash.z.wallet.sdk.rpc.Service.BlockID.getDefaultInstance() : block_; + } else { + return blockBuilder_.getMessage(); + } + } + /** + *
+       * block identifier, height or hash
+       * 
+ * + * .cash.z.wallet.sdk.rpc.BlockID block = 1; + */ + public Builder setBlock(cash.z.wallet.sdk.rpc.Service.BlockID value) { + if (blockBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + block_ = value; + onChanged(); + } else { + blockBuilder_.setMessage(value); + } + + return this; + } + /** + *
+       * block identifier, height or hash
+       * 
+ * + * .cash.z.wallet.sdk.rpc.BlockID block = 1; + */ + public Builder setBlock( + cash.z.wallet.sdk.rpc.Service.BlockID.Builder builderForValue) { + if (blockBuilder_ == null) { + block_ = builderForValue.build(); + onChanged(); + } else { + blockBuilder_.setMessage(builderForValue.build()); + } + + return this; + } + /** + *
+       * block identifier, height or hash
+       * 
+ * + * .cash.z.wallet.sdk.rpc.BlockID block = 1; + */ + public Builder mergeBlock(cash.z.wallet.sdk.rpc.Service.BlockID value) { + if (blockBuilder_ == null) { + if (block_ != null) { + block_ = + cash.z.wallet.sdk.rpc.Service.BlockID.newBuilder(block_).mergeFrom(value).buildPartial(); + } else { + block_ = value; + } + onChanged(); + } else { + blockBuilder_.mergeFrom(value); + } + + return this; + } + /** + *
+       * block identifier, height or hash
+       * 
+ * + * .cash.z.wallet.sdk.rpc.BlockID block = 1; + */ + public Builder clearBlock() { + if (blockBuilder_ == null) { + block_ = null; + onChanged(); + } else { + block_ = null; + blockBuilder_ = null; + } + + return this; + } + /** + *
+       * block identifier, height or hash
+       * 
+ * + * .cash.z.wallet.sdk.rpc.BlockID block = 1; + */ + public cash.z.wallet.sdk.rpc.Service.BlockID.Builder getBlockBuilder() { + + onChanged(); + return getBlockFieldBuilder().getBuilder(); + } + /** + *
+       * block identifier, height or hash
+       * 
+ * + * .cash.z.wallet.sdk.rpc.BlockID block = 1; + */ + public cash.z.wallet.sdk.rpc.Service.BlockIDOrBuilder getBlockOrBuilder() { + if (blockBuilder_ != null) { + return blockBuilder_.getMessageOrBuilder(); + } else { + return block_ == null ? + cash.z.wallet.sdk.rpc.Service.BlockID.getDefaultInstance() : block_; + } + } + /** + *
+       * block identifier, height or hash
+       * 
+ * + * .cash.z.wallet.sdk.rpc.BlockID block = 1; + */ + private com.google.protobuf.SingleFieldBuilderV3< + cash.z.wallet.sdk.rpc.Service.BlockID, cash.z.wallet.sdk.rpc.Service.BlockID.Builder, cash.z.wallet.sdk.rpc.Service.BlockIDOrBuilder> + getBlockFieldBuilder() { + if (blockBuilder_ == null) { + blockBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + cash.z.wallet.sdk.rpc.Service.BlockID, cash.z.wallet.sdk.rpc.Service.BlockID.Builder, cash.z.wallet.sdk.rpc.Service.BlockIDOrBuilder>( + getBlock(), + getParentForChildren(), + isClean()); + block_ = null; + } + return blockBuilder_; + } + + private long index_ ; + /** + *
+       * index within the block
+       * 
+ * + * uint64 index = 2; + * @return The index. + */ + @java.lang.Override + public long getIndex() { + return index_; + } + /** + *
+       * index within the block
+       * 
+ * + * uint64 index = 2; + * @param value The index to set. + * @return This builder for chaining. + */ + public Builder setIndex(long value) { + + index_ = value; + onChanged(); + return this; + } + /** + *
+       * index within the block
+       * 
+ * + * uint64 index = 2; + * @return This builder for chaining. + */ + public Builder clearIndex() { + + index_ = 0L; + onChanged(); + return this; + } + + private com.google.protobuf.ByteString hash_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+       * transaction ID (hash, txid)
+       * 
+ * + * bytes hash = 3; + * @return The hash. + */ + @java.lang.Override + public com.google.protobuf.ByteString getHash() { + return hash_; + } + /** + *
+       * transaction ID (hash, txid)
+       * 
+ * + * bytes hash = 3; + * @param value The hash to set. + * @return This builder for chaining. + */ + public Builder setHash(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + + hash_ = value; + onChanged(); + return this; + } + /** + *
+       * transaction ID (hash, txid)
+       * 
+ * + * bytes hash = 3; + * @return This builder for chaining. + */ + public Builder clearHash() { + + hash_ = getDefaultInstance().getHash(); + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.TxFilter) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.TxFilter) + private static final cash.z.wallet.sdk.rpc.Service.TxFilter DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.Service.TxFilter(); + } + + public static cash.z.wallet.sdk.rpc.Service.TxFilter getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public TxFilter parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new TxFilter(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.TxFilter getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface RawTransactionOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.RawTransaction) + com.google.protobuf.MessageOrBuilder { + + /** + *
+     * exact data returned by Zcash 'getrawtransaction'
+     * 
+ * + * bytes data = 1; + * @return The data. + */ + com.google.protobuf.ByteString getData(); + + /** + *
+     * height that the transaction was mined (or -1)
+     * 
+ * + * uint64 height = 2; + * @return The height. + */ + long getHeight(); + } + /** + *
+   * RawTransaction contains the complete transaction data. It also optionally includes 
+   * the block height in which the transaction was included.
+   * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.RawTransaction} + */ + public static final class RawTransaction extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.RawTransaction) + RawTransactionOrBuilder { + private static final long serialVersionUID = 0L; + // Use RawTransaction.newBuilder() to construct. + private RawTransaction(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private RawTransaction() { + data_ = com.google.protobuf.ByteString.EMPTY; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new RawTransaction(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private RawTransaction( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + + data_ = input.readBytes(); + break; + } + case 16: { + + height_ = input.readUInt64(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_RawTransaction_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_RawTransaction_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.RawTransaction.class, cash.z.wallet.sdk.rpc.Service.RawTransaction.Builder.class); + } + + public static final int DATA_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString data_; + /** + *
+     * exact data returned by Zcash 'getrawtransaction'
+     * 
+ * + * bytes data = 1; + * @return The data. + */ + @java.lang.Override + public com.google.protobuf.ByteString getData() { + return data_; + } + + public static final int HEIGHT_FIELD_NUMBER = 2; + private long height_; + /** + *
+     * height that the transaction was mined (or -1)
+     * 
+ * + * uint64 height = 2; + * @return The height. + */ + @java.lang.Override + public long getHeight() { + return height_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!data_.isEmpty()) { + output.writeBytes(1, data_); + } + if (height_ != 0L) { + output.writeUInt64(2, height_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!data_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, data_); + } + if (height_ != 0L) { + size += com.google.protobuf.CodedOutputStream + .computeUInt64Size(2, height_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.Service.RawTransaction)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.Service.RawTransaction other = (cash.z.wallet.sdk.rpc.Service.RawTransaction) obj; + + if (!getData() + .equals(other.getData())) return false; + if (getHeight() + != other.getHeight()) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + DATA_FIELD_NUMBER; + hash = (53 * hash) + getData().hashCode(); + hash = (37 * hash) + HEIGHT_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashLong( + getHeight()); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.Service.RawTransaction parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.RawTransaction parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.RawTransaction parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.RawTransaction parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.RawTransaction parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.RawTransaction parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.RawTransaction parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.RawTransaction parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.RawTransaction parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.RawTransaction parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.RawTransaction parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.RawTransaction parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.Service.RawTransaction prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * RawTransaction contains the complete transaction data. It also optionally includes 
+     * the block height in which the transaction was included.
+     * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.RawTransaction} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.RawTransaction) + cash.z.wallet.sdk.rpc.Service.RawTransactionOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_RawTransaction_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_RawTransaction_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.RawTransaction.class, cash.z.wallet.sdk.rpc.Service.RawTransaction.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.Service.RawTransaction.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + data_ = com.google.protobuf.ByteString.EMPTY; + + height_ = 0L; + + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_RawTransaction_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.RawTransaction getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.Service.RawTransaction.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.RawTransaction build() { + cash.z.wallet.sdk.rpc.Service.RawTransaction result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.RawTransaction buildPartial() { + cash.z.wallet.sdk.rpc.Service.RawTransaction result = new cash.z.wallet.sdk.rpc.Service.RawTransaction(this); + result.data_ = data_; + result.height_ = height_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.Service.RawTransaction) { + return mergeFrom((cash.z.wallet.sdk.rpc.Service.RawTransaction)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.Service.RawTransaction other) { + if (other == cash.z.wallet.sdk.rpc.Service.RawTransaction.getDefaultInstance()) return this; + if (other.getData() != com.google.protobuf.ByteString.EMPTY) { + setData(other.getData()); + } + if (other.getHeight() != 0L) { + setHeight(other.getHeight()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.Service.RawTransaction parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.Service.RawTransaction) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private com.google.protobuf.ByteString data_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+       * exact data returned by Zcash 'getrawtransaction'
+       * 
+ * + * bytes data = 1; + * @return The data. + */ + @java.lang.Override + public com.google.protobuf.ByteString getData() { + return data_; + } + /** + *
+       * exact data returned by Zcash 'getrawtransaction'
+       * 
+ * + * bytes data = 1; + * @param value The data to set. + * @return This builder for chaining. + */ + public Builder setData(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + + data_ = value; + onChanged(); + return this; + } + /** + *
+       * exact data returned by Zcash 'getrawtransaction'
+       * 
+ * + * bytes data = 1; + * @return This builder for chaining. + */ + public Builder clearData() { + + data_ = getDefaultInstance().getData(); + onChanged(); + return this; + } + + private long height_ ; + /** + *
+       * height that the transaction was mined (or -1)
+       * 
+ * + * uint64 height = 2; + * @return The height. + */ + @java.lang.Override + public long getHeight() { + return height_; + } + /** + *
+       * height that the transaction was mined (or -1)
+       * 
+ * + * uint64 height = 2; + * @param value The height to set. + * @return This builder for chaining. + */ + public Builder setHeight(long value) { + + height_ = value; + onChanged(); + return this; + } + /** + *
+       * height that the transaction was mined (or -1)
+       * 
+ * + * uint64 height = 2; + * @return This builder for chaining. + */ + public Builder clearHeight() { + + height_ = 0L; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.RawTransaction) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.RawTransaction) + private static final cash.z.wallet.sdk.rpc.Service.RawTransaction DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.Service.RawTransaction(); + } + + public static cash.z.wallet.sdk.rpc.Service.RawTransaction getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public RawTransaction parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new RawTransaction(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.RawTransaction getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface SendResponseOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.SendResponse) + com.google.protobuf.MessageOrBuilder { + + /** + * int32 errorCode = 1; + * @return The errorCode. + */ + int getErrorCode(); + + /** + * string errorMessage = 2; + * @return The errorMessage. + */ + java.lang.String getErrorMessage(); + /** + * string errorMessage = 2; + * @return The bytes for errorMessage. + */ + com.google.protobuf.ByteString + getErrorMessageBytes(); + } + /** + *
+   * A SendResponse encodes an error code and a string. It is currently used
+   * only by SendTransaction(). If error code is zero, the operation was
+   * successful; if non-zero, it and the message specify the failure.
+   * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.SendResponse} + */ + public static final class SendResponse extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.SendResponse) + SendResponseOrBuilder { + private static final long serialVersionUID = 0L; + // Use SendResponse.newBuilder() to construct. + private SendResponse(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private SendResponse() { + errorMessage_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new SendResponse(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private SendResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: { + + errorCode_ = input.readInt32(); + break; + } + case 18: { + java.lang.String s = input.readStringRequireUtf8(); + + errorMessage_ = s; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_SendResponse_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_SendResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.SendResponse.class, cash.z.wallet.sdk.rpc.Service.SendResponse.Builder.class); + } + + public static final int ERRORCODE_FIELD_NUMBER = 1; + private int errorCode_; + /** + * int32 errorCode = 1; + * @return The errorCode. + */ + @java.lang.Override + public int getErrorCode() { + return errorCode_; + } + + public static final int ERRORMESSAGE_FIELD_NUMBER = 2; + private volatile java.lang.Object errorMessage_; + /** + * string errorMessage = 2; + * @return The errorMessage. + */ + @java.lang.Override + public java.lang.String getErrorMessage() { + java.lang.Object ref = errorMessage_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + errorMessage_ = s; + return s; + } + } + /** + * string errorMessage = 2; + * @return The bytes for errorMessage. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getErrorMessageBytes() { + java.lang.Object ref = errorMessage_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + errorMessage_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (errorCode_ != 0) { + output.writeInt32(1, errorCode_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(errorMessage_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, errorMessage_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (errorCode_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(1, errorCode_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(errorMessage_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, errorMessage_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.Service.SendResponse)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.Service.SendResponse other = (cash.z.wallet.sdk.rpc.Service.SendResponse) obj; + + if (getErrorCode() + != other.getErrorCode()) return false; + if (!getErrorMessage() + .equals(other.getErrorMessage())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + ERRORCODE_FIELD_NUMBER; + hash = (53 * hash) + getErrorCode(); + hash = (37 * hash) + ERRORMESSAGE_FIELD_NUMBER; + hash = (53 * hash) + getErrorMessage().hashCode(); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.Service.SendResponse parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.SendResponse parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.SendResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.SendResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.SendResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.SendResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.SendResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.SendResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.SendResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.SendResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.SendResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.SendResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.Service.SendResponse prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * A SendResponse encodes an error code and a string. It is currently used
+     * only by SendTransaction(). If error code is zero, the operation was
+     * successful; if non-zero, it and the message specify the failure.
+     * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.SendResponse} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.SendResponse) + cash.z.wallet.sdk.rpc.Service.SendResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_SendResponse_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_SendResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.SendResponse.class, cash.z.wallet.sdk.rpc.Service.SendResponse.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.Service.SendResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + errorCode_ = 0; + + errorMessage_ = ""; + + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_SendResponse_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.SendResponse getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.Service.SendResponse.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.SendResponse build() { + cash.z.wallet.sdk.rpc.Service.SendResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.SendResponse buildPartial() { + cash.z.wallet.sdk.rpc.Service.SendResponse result = new cash.z.wallet.sdk.rpc.Service.SendResponse(this); + result.errorCode_ = errorCode_; + result.errorMessage_ = errorMessage_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.Service.SendResponse) { + return mergeFrom((cash.z.wallet.sdk.rpc.Service.SendResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.Service.SendResponse other) { + if (other == cash.z.wallet.sdk.rpc.Service.SendResponse.getDefaultInstance()) return this; + if (other.getErrorCode() != 0) { + setErrorCode(other.getErrorCode()); + } + if (!other.getErrorMessage().isEmpty()) { + errorMessage_ = other.errorMessage_; + onChanged(); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.Service.SendResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.Service.SendResponse) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private int errorCode_ ; + /** + * int32 errorCode = 1; + * @return The errorCode. + */ + @java.lang.Override + public int getErrorCode() { + return errorCode_; + } + /** + * int32 errorCode = 1; + * @param value The errorCode to set. + * @return This builder for chaining. + */ + public Builder setErrorCode(int value) { + + errorCode_ = value; + onChanged(); + return this; + } + /** + * int32 errorCode = 1; + * @return This builder for chaining. + */ + public Builder clearErrorCode() { + + errorCode_ = 0; + onChanged(); + return this; + } + + private java.lang.Object errorMessage_ = ""; + /** + * string errorMessage = 2; + * @return The errorMessage. + */ + public java.lang.String getErrorMessage() { + java.lang.Object ref = errorMessage_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + errorMessage_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * string errorMessage = 2; + * @return The bytes for errorMessage. + */ + public com.google.protobuf.ByteString + getErrorMessageBytes() { + java.lang.Object ref = errorMessage_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + errorMessage_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string errorMessage = 2; + * @param value The errorMessage to set. + * @return This builder for chaining. + */ + public Builder setErrorMessage( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + errorMessage_ = value; + onChanged(); + return this; + } + /** + * string errorMessage = 2; + * @return This builder for chaining. + */ + public Builder clearErrorMessage() { + + errorMessage_ = getDefaultInstance().getErrorMessage(); + onChanged(); + return this; + } + /** + * string errorMessage = 2; + * @param value The bytes for errorMessage to set. + * @return This builder for chaining. + */ + public Builder setErrorMessageBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + errorMessage_ = value; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.SendResponse) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.SendResponse) + private static final cash.z.wallet.sdk.rpc.Service.SendResponse DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.Service.SendResponse(); + } + + public static cash.z.wallet.sdk.rpc.Service.SendResponse getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public SendResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new SendResponse(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.SendResponse getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface ChainSpecOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.ChainSpec) + com.google.protobuf.MessageOrBuilder { + } + /** + *
+   * Chainspec is a placeholder to allow specification of a particular chain fork.
+   * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.ChainSpec} + */ + public static final class ChainSpec extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.ChainSpec) + ChainSpecOrBuilder { + private static final long serialVersionUID = 0L; + // Use ChainSpec.newBuilder() to construct. + private ChainSpec(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private ChainSpec() { + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new ChainSpec(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private ChainSpec( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_ChainSpec_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_ChainSpec_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.ChainSpec.class, cash.z.wallet.sdk.rpc.Service.ChainSpec.Builder.class); + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.Service.ChainSpec)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.Service.ChainSpec other = (cash.z.wallet.sdk.rpc.Service.ChainSpec) obj; + + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.Service.ChainSpec parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.ChainSpec parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.ChainSpec parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.ChainSpec parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.ChainSpec parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.ChainSpec parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.ChainSpec parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.ChainSpec parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.ChainSpec parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.ChainSpec parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.ChainSpec parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.ChainSpec parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.Service.ChainSpec prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * Chainspec is a placeholder to allow specification of a particular chain fork.
+     * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.ChainSpec} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.ChainSpec) + cash.z.wallet.sdk.rpc.Service.ChainSpecOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_ChainSpec_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_ChainSpec_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.ChainSpec.class, cash.z.wallet.sdk.rpc.Service.ChainSpec.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.Service.ChainSpec.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_ChainSpec_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.ChainSpec getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.Service.ChainSpec.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.ChainSpec build() { + cash.z.wallet.sdk.rpc.Service.ChainSpec result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.ChainSpec buildPartial() { + cash.z.wallet.sdk.rpc.Service.ChainSpec result = new cash.z.wallet.sdk.rpc.Service.ChainSpec(this); + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.Service.ChainSpec) { + return mergeFrom((cash.z.wallet.sdk.rpc.Service.ChainSpec)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.Service.ChainSpec other) { + if (other == cash.z.wallet.sdk.rpc.Service.ChainSpec.getDefaultInstance()) return this; + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.Service.ChainSpec parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.Service.ChainSpec) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.ChainSpec) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.ChainSpec) + private static final cash.z.wallet.sdk.rpc.Service.ChainSpec DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.Service.ChainSpec(); + } + + public static cash.z.wallet.sdk.rpc.Service.ChainSpec getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public ChainSpec parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new ChainSpec(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.ChainSpec getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface EmptyOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.Empty) + com.google.protobuf.MessageOrBuilder { + } + /** + *
+   * Empty is for gRPCs that take no arguments, currently only GetLightdInfo.
+   * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.Empty} + */ + public static final class Empty extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.Empty) + EmptyOrBuilder { + private static final long serialVersionUID = 0L; + // Use Empty.newBuilder() to construct. + private Empty(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Empty() { + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new Empty(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Empty( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_Empty_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_Empty_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.Empty.class, cash.z.wallet.sdk.rpc.Service.Empty.Builder.class); + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.Service.Empty)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.Service.Empty other = (cash.z.wallet.sdk.rpc.Service.Empty) obj; + + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.Service.Empty parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.Empty parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.Empty parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.Empty parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.Empty parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.Empty parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.Empty parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.Empty parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.Empty parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.Empty parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.Empty parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.Empty parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.Service.Empty prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * Empty is for gRPCs that take no arguments, currently only GetLightdInfo.
+     * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.Empty} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.Empty) + cash.z.wallet.sdk.rpc.Service.EmptyOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_Empty_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_Empty_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.Empty.class, cash.z.wallet.sdk.rpc.Service.Empty.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.Service.Empty.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_Empty_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.Empty getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.Service.Empty.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.Empty build() { + cash.z.wallet.sdk.rpc.Service.Empty result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.Empty buildPartial() { + cash.z.wallet.sdk.rpc.Service.Empty result = new cash.z.wallet.sdk.rpc.Service.Empty(this); + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.Service.Empty) { + return mergeFrom((cash.z.wallet.sdk.rpc.Service.Empty)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.Service.Empty other) { + if (other == cash.z.wallet.sdk.rpc.Service.Empty.getDefaultInstance()) return this; + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.Service.Empty parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.Service.Empty) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.Empty) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.Empty) + private static final cash.z.wallet.sdk.rpc.Service.Empty DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.Service.Empty(); + } + + public static cash.z.wallet.sdk.rpc.Service.Empty getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public Empty parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Empty(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.Empty getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface LightdInfoOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.LightdInfo) + com.google.protobuf.MessageOrBuilder { + + /** + * string version = 1; + * @return The version. + */ + java.lang.String getVersion(); + /** + * string version = 1; + * @return The bytes for version. + */ + com.google.protobuf.ByteString + getVersionBytes(); + + /** + * string vendor = 2; + * @return The vendor. + */ + java.lang.String getVendor(); + /** + * string vendor = 2; + * @return The bytes for vendor. + */ + com.google.protobuf.ByteString + getVendorBytes(); + + /** + *
+     * true
+     * 
+ * + * bool taddrSupport = 3; + * @return The taddrSupport. + */ + boolean getTaddrSupport(); + + /** + *
+     * either "main" or "test"
+     * 
+ * + * string chainName = 4; + * @return The chainName. + */ + java.lang.String getChainName(); + /** + *
+     * either "main" or "test"
+     * 
+ * + * string chainName = 4; + * @return The bytes for chainName. + */ + com.google.protobuf.ByteString + getChainNameBytes(); + + /** + *
+     * depends on mainnet or testnet
+     * 
+ * + * uint64 saplingActivationHeight = 5; + * @return The saplingActivationHeight. + */ + long getSaplingActivationHeight(); + + /** + *
+     * protocol identifier, see consensus/upgrades.cpp
+     * 
+ * + * string consensusBranchId = 6; + * @return The consensusBranchId. + */ + java.lang.String getConsensusBranchId(); + /** + *
+     * protocol identifier, see consensus/upgrades.cpp
+     * 
+ * + * string consensusBranchId = 6; + * @return The bytes for consensusBranchId. + */ + com.google.protobuf.ByteString + getConsensusBranchIdBytes(); + + /** + *
+     * latest block on the best chain
+     * 
+ * + * uint64 blockHeight = 7; + * @return The blockHeight. + */ + long getBlockHeight(); + + /** + * string gitCommit = 8; + * @return The gitCommit. + */ + java.lang.String getGitCommit(); + /** + * string gitCommit = 8; + * @return The bytes for gitCommit. + */ + com.google.protobuf.ByteString + getGitCommitBytes(); + + /** + * string branch = 9; + * @return The branch. + */ + java.lang.String getBranch(); + /** + * string branch = 9; + * @return The bytes for branch. + */ + com.google.protobuf.ByteString + getBranchBytes(); + + /** + * string buildDate = 10; + * @return The buildDate. + */ + java.lang.String getBuildDate(); + /** + * string buildDate = 10; + * @return The bytes for buildDate. + */ + com.google.protobuf.ByteString + getBuildDateBytes(); + + /** + * string buildUser = 11; + * @return The buildUser. + */ + java.lang.String getBuildUser(); + /** + * string buildUser = 11; + * @return The bytes for buildUser. + */ + com.google.protobuf.ByteString + getBuildUserBytes(); + + /** + *
+     * less than tip height if pirated is syncing
+     * 
+ * + * uint64 estimatedHeight = 12; + * @return The estimatedHeight. + */ + long getEstimatedHeight(); + + /** + *
+     * example: "v4.1.1-877212414"
+     * 
+ * + * string piratedBuild = 13; + * @return The piratedBuild. + */ + java.lang.String getPiratedBuild(); + /** + *
+     * example: "v4.1.1-877212414"
+     * 
+ * + * string piratedBuild = 13; + * @return The bytes for piratedBuild. + */ + com.google.protobuf.ByteString + getPiratedBuildBytes(); + + /** + *
+     * example: "/MagicBean:4.1.1/"
+     * 
+ * + * string piratedSubversion = 14; + * @return The piratedSubversion. + */ + java.lang.String getPiratedSubversion(); + /** + *
+     * example: "/MagicBean:4.1.1/"
+     * 
+ * + * string piratedSubversion = 14; + * @return The bytes for piratedSubversion. + */ + com.google.protobuf.ByteString + getPiratedSubversionBytes(); + } + /** + *
+   * LightdInfo returns various information about this lightwalletd instance
+   * and the state of the blockchain.
+   * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.LightdInfo} + */ + public static final class LightdInfo extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.LightdInfo) + LightdInfoOrBuilder { + private static final long serialVersionUID = 0L; + // Use LightdInfo.newBuilder() to construct. + private LightdInfo(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private LightdInfo() { + version_ = ""; + vendor_ = ""; + chainName_ = ""; + consensusBranchId_ = ""; + gitCommit_ = ""; + branch_ = ""; + buildDate_ = ""; + buildUser_ = ""; + piratedBuild_ = ""; + piratedSubversion_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new LightdInfo(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private LightdInfo( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + java.lang.String s = input.readStringRequireUtf8(); + + version_ = s; + break; + } + case 18: { + java.lang.String s = input.readStringRequireUtf8(); + + vendor_ = s; + break; + } + case 24: { + + taddrSupport_ = input.readBool(); + break; + } + case 34: { + java.lang.String s = input.readStringRequireUtf8(); + + chainName_ = s; + break; + } + case 40: { + + saplingActivationHeight_ = input.readUInt64(); + break; + } + case 50: { + java.lang.String s = input.readStringRequireUtf8(); + + consensusBranchId_ = s; + break; + } + case 56: { + + blockHeight_ = input.readUInt64(); + break; + } + case 66: { + java.lang.String s = input.readStringRequireUtf8(); + + gitCommit_ = s; + break; + } + case 74: { + java.lang.String s = input.readStringRequireUtf8(); + + branch_ = s; + break; + } + case 82: { + java.lang.String s = input.readStringRequireUtf8(); + + buildDate_ = s; + break; + } + case 90: { + java.lang.String s = input.readStringRequireUtf8(); + + buildUser_ = s; + break; + } + case 96: { + + estimatedHeight_ = input.readUInt64(); + break; + } + case 106: { + java.lang.String s = input.readStringRequireUtf8(); + + piratedBuild_ = s; + break; + } + case 114: { + java.lang.String s = input.readStringRequireUtf8(); + + piratedSubversion_ = s; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_LightdInfo_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_LightdInfo_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.LightdInfo.class, cash.z.wallet.sdk.rpc.Service.LightdInfo.Builder.class); + } + + public static final int VERSION_FIELD_NUMBER = 1; + private volatile java.lang.Object version_; + /** + * string version = 1; + * @return The version. + */ + @java.lang.Override + public java.lang.String getVersion() { + java.lang.Object ref = version_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + version_ = s; + return s; + } + } + /** + * string version = 1; + * @return The bytes for version. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getVersionBytes() { + java.lang.Object ref = version_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + version_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int VENDOR_FIELD_NUMBER = 2; + private volatile java.lang.Object vendor_; + /** + * string vendor = 2; + * @return The vendor. + */ + @java.lang.Override + public java.lang.String getVendor() { + java.lang.Object ref = vendor_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + vendor_ = s; + return s; + } + } + /** + * string vendor = 2; + * @return The bytes for vendor. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getVendorBytes() { + java.lang.Object ref = vendor_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + vendor_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int TADDRSUPPORT_FIELD_NUMBER = 3; + private boolean taddrSupport_; + /** + *
+     * true
+     * 
+ * + * bool taddrSupport = 3; + * @return The taddrSupport. + */ + @java.lang.Override + public boolean getTaddrSupport() { + return taddrSupport_; + } + + public static final int CHAINNAME_FIELD_NUMBER = 4; + private volatile java.lang.Object chainName_; + /** + *
+     * either "main" or "test"
+     * 
+ * + * string chainName = 4; + * @return The chainName. + */ + @java.lang.Override + public java.lang.String getChainName() { + java.lang.Object ref = chainName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + chainName_ = s; + return s; + } + } + /** + *
+     * either "main" or "test"
+     * 
+ * + * string chainName = 4; + * @return The bytes for chainName. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getChainNameBytes() { + java.lang.Object ref = chainName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + chainName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int SAPLINGACTIVATIONHEIGHT_FIELD_NUMBER = 5; + private long saplingActivationHeight_; + /** + *
+     * depends on mainnet or testnet
+     * 
+ * + * uint64 saplingActivationHeight = 5; + * @return The saplingActivationHeight. + */ + @java.lang.Override + public long getSaplingActivationHeight() { + return saplingActivationHeight_; + } + + public static final int CONSENSUSBRANCHID_FIELD_NUMBER = 6; + private volatile java.lang.Object consensusBranchId_; + /** + *
+     * protocol identifier, see consensus/upgrades.cpp
+     * 
+ * + * string consensusBranchId = 6; + * @return The consensusBranchId. + */ + @java.lang.Override + public java.lang.String getConsensusBranchId() { + java.lang.Object ref = consensusBranchId_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + consensusBranchId_ = s; + return s; + } + } + /** + *
+     * protocol identifier, see consensus/upgrades.cpp
+     * 
+ * + * string consensusBranchId = 6; + * @return The bytes for consensusBranchId. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getConsensusBranchIdBytes() { + java.lang.Object ref = consensusBranchId_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + consensusBranchId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int BLOCKHEIGHT_FIELD_NUMBER = 7; + private long blockHeight_; + /** + *
+     * latest block on the best chain
+     * 
+ * + * uint64 blockHeight = 7; + * @return The blockHeight. + */ + @java.lang.Override + public long getBlockHeight() { + return blockHeight_; + } + + public static final int GITCOMMIT_FIELD_NUMBER = 8; + private volatile java.lang.Object gitCommit_; + /** + * string gitCommit = 8; + * @return The gitCommit. + */ + @java.lang.Override + public java.lang.String getGitCommit() { + java.lang.Object ref = gitCommit_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + gitCommit_ = s; + return s; + } + } + /** + * string gitCommit = 8; + * @return The bytes for gitCommit. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getGitCommitBytes() { + java.lang.Object ref = gitCommit_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + gitCommit_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int BRANCH_FIELD_NUMBER = 9; + private volatile java.lang.Object branch_; + /** + * string branch = 9; + * @return The branch. + */ + @java.lang.Override + public java.lang.String getBranch() { + java.lang.Object ref = branch_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + branch_ = s; + return s; + } + } + /** + * string branch = 9; + * @return The bytes for branch. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getBranchBytes() { + java.lang.Object ref = branch_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + branch_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int BUILDDATE_FIELD_NUMBER = 10; + private volatile java.lang.Object buildDate_; + /** + * string buildDate = 10; + * @return The buildDate. + */ + @java.lang.Override + public java.lang.String getBuildDate() { + java.lang.Object ref = buildDate_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + buildDate_ = s; + return s; + } + } + /** + * string buildDate = 10; + * @return The bytes for buildDate. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getBuildDateBytes() { + java.lang.Object ref = buildDate_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + buildDate_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int BUILDUSER_FIELD_NUMBER = 11; + private volatile java.lang.Object buildUser_; + /** + * string buildUser = 11; + * @return The buildUser. + */ + @java.lang.Override + public java.lang.String getBuildUser() { + java.lang.Object ref = buildUser_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + buildUser_ = s; + return s; + } + } + /** + * string buildUser = 11; + * @return The bytes for buildUser. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getBuildUserBytes() { + java.lang.Object ref = buildUser_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + buildUser_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int ESTIMATEDHEIGHT_FIELD_NUMBER = 12; + private long estimatedHeight_; + /** + *
+     * less than tip height if pirated is syncing
+     * 
+ * + * uint64 estimatedHeight = 12; + * @return The estimatedHeight. + */ + @java.lang.Override + public long getEstimatedHeight() { + return estimatedHeight_; + } + + public static final int PIRATEDBUILD_FIELD_NUMBER = 13; + private volatile java.lang.Object piratedBuild_; + /** + *
+     * example: "v4.1.1-877212414"
+     * 
+ * + * string piratedBuild = 13; + * @return The piratedBuild. + */ + @java.lang.Override + public java.lang.String getPiratedBuild() { + java.lang.Object ref = piratedBuild_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + piratedBuild_ = s; + return s; + } + } + /** + *
+     * example: "v4.1.1-877212414"
+     * 
+ * + * string piratedBuild = 13; + * @return The bytes for piratedBuild. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getPiratedBuildBytes() { + java.lang.Object ref = piratedBuild_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + piratedBuild_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int PIRATEDSUBVERSION_FIELD_NUMBER = 14; + private volatile java.lang.Object piratedSubversion_; + /** + *
+     * example: "/MagicBean:4.1.1/"
+     * 
+ * + * string piratedSubversion = 14; + * @return The piratedSubversion. + */ + @java.lang.Override + public java.lang.String getPiratedSubversion() { + java.lang.Object ref = piratedSubversion_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + piratedSubversion_ = s; + return s; + } + } + /** + *
+     * example: "/MagicBean:4.1.1/"
+     * 
+ * + * string piratedSubversion = 14; + * @return The bytes for piratedSubversion. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getPiratedSubversionBytes() { + java.lang.Object ref = piratedSubversion_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + piratedSubversion_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(version_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, version_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(vendor_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 2, vendor_); + } + if (taddrSupport_ != false) { + output.writeBool(3, taddrSupport_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(chainName_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 4, chainName_); + } + if (saplingActivationHeight_ != 0L) { + output.writeUInt64(5, saplingActivationHeight_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(consensusBranchId_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 6, consensusBranchId_); + } + if (blockHeight_ != 0L) { + output.writeUInt64(7, blockHeight_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(gitCommit_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 8, gitCommit_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(branch_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 9, branch_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(buildDate_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 10, buildDate_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(buildUser_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 11, buildUser_); + } + if (estimatedHeight_ != 0L) { + output.writeUInt64(12, estimatedHeight_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(piratedBuild_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 13, piratedBuild_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(piratedSubversion_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 14, piratedSubversion_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(version_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, version_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(vendor_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, vendor_); + } + if (taddrSupport_ != false) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(3, taddrSupport_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(chainName_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, chainName_); + } + if (saplingActivationHeight_ != 0L) { + size += com.google.protobuf.CodedOutputStream + .computeUInt64Size(5, saplingActivationHeight_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(consensusBranchId_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, consensusBranchId_); + } + if (blockHeight_ != 0L) { + size += com.google.protobuf.CodedOutputStream + .computeUInt64Size(7, blockHeight_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(gitCommit_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(8, gitCommit_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(branch_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(9, branch_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(buildDate_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(10, buildDate_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(buildUser_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(11, buildUser_); + } + if (estimatedHeight_ != 0L) { + size += com.google.protobuf.CodedOutputStream + .computeUInt64Size(12, estimatedHeight_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(piratedBuild_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(13, piratedBuild_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(piratedSubversion_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(14, piratedSubversion_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.Service.LightdInfo)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.Service.LightdInfo other = (cash.z.wallet.sdk.rpc.Service.LightdInfo) obj; + + if (!getVersion() + .equals(other.getVersion())) return false; + if (!getVendor() + .equals(other.getVendor())) return false; + if (getTaddrSupport() + != other.getTaddrSupport()) return false; + if (!getChainName() + .equals(other.getChainName())) return false; + if (getSaplingActivationHeight() + != other.getSaplingActivationHeight()) return false; + if (!getConsensusBranchId() + .equals(other.getConsensusBranchId())) return false; + if (getBlockHeight() + != other.getBlockHeight()) return false; + if (!getGitCommit() + .equals(other.getGitCommit())) return false; + if (!getBranch() + .equals(other.getBranch())) return false; + if (!getBuildDate() + .equals(other.getBuildDate())) return false; + if (!getBuildUser() + .equals(other.getBuildUser())) return false; + if (getEstimatedHeight() + != other.getEstimatedHeight()) return false; + if (!getPiratedBuild() + .equals(other.getPiratedBuild())) return false; + if (!getPiratedSubversion() + .equals(other.getPiratedSubversion())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + VERSION_FIELD_NUMBER; + hash = (53 * hash) + getVersion().hashCode(); + hash = (37 * hash) + VENDOR_FIELD_NUMBER; + hash = (53 * hash) + getVendor().hashCode(); + hash = (37 * hash) + TADDRSUPPORT_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( + getTaddrSupport()); + hash = (37 * hash) + CHAINNAME_FIELD_NUMBER; + hash = (53 * hash) + getChainName().hashCode(); + hash = (37 * hash) + SAPLINGACTIVATIONHEIGHT_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashLong( + getSaplingActivationHeight()); + hash = (37 * hash) + CONSENSUSBRANCHID_FIELD_NUMBER; + hash = (53 * hash) + getConsensusBranchId().hashCode(); + hash = (37 * hash) + BLOCKHEIGHT_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashLong( + getBlockHeight()); + hash = (37 * hash) + GITCOMMIT_FIELD_NUMBER; + hash = (53 * hash) + getGitCommit().hashCode(); + hash = (37 * hash) + BRANCH_FIELD_NUMBER; + hash = (53 * hash) + getBranch().hashCode(); + hash = (37 * hash) + BUILDDATE_FIELD_NUMBER; + hash = (53 * hash) + getBuildDate().hashCode(); + hash = (37 * hash) + BUILDUSER_FIELD_NUMBER; + hash = (53 * hash) + getBuildUser().hashCode(); + hash = (37 * hash) + ESTIMATEDHEIGHT_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashLong( + getEstimatedHeight()); + hash = (37 * hash) + PIRATEDBUILD_FIELD_NUMBER; + hash = (53 * hash) + getPiratedBuild().hashCode(); + hash = (37 * hash) + PIRATEDSUBVERSION_FIELD_NUMBER; + hash = (53 * hash) + getPiratedSubversion().hashCode(); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.Service.LightdInfo parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.LightdInfo parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.LightdInfo parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.LightdInfo parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.LightdInfo parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.LightdInfo parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.LightdInfo parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.LightdInfo parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.LightdInfo parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.LightdInfo parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.LightdInfo parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.LightdInfo parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.Service.LightdInfo prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * LightdInfo returns various information about this lightwalletd instance
+     * and the state of the blockchain.
+     * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.LightdInfo} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.LightdInfo) + cash.z.wallet.sdk.rpc.Service.LightdInfoOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_LightdInfo_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_LightdInfo_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.LightdInfo.class, cash.z.wallet.sdk.rpc.Service.LightdInfo.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.Service.LightdInfo.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + version_ = ""; + + vendor_ = ""; + + taddrSupport_ = false; + + chainName_ = ""; + + saplingActivationHeight_ = 0L; + + consensusBranchId_ = ""; + + blockHeight_ = 0L; + + gitCommit_ = ""; + + branch_ = ""; + + buildDate_ = ""; + + buildUser_ = ""; + + estimatedHeight_ = 0L; + + piratedBuild_ = ""; + + piratedSubversion_ = ""; + + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_LightdInfo_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.LightdInfo getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.Service.LightdInfo.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.LightdInfo build() { + cash.z.wallet.sdk.rpc.Service.LightdInfo result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.LightdInfo buildPartial() { + cash.z.wallet.sdk.rpc.Service.LightdInfo result = new cash.z.wallet.sdk.rpc.Service.LightdInfo(this); + result.version_ = version_; + result.vendor_ = vendor_; + result.taddrSupport_ = taddrSupport_; + result.chainName_ = chainName_; + result.saplingActivationHeight_ = saplingActivationHeight_; + result.consensusBranchId_ = consensusBranchId_; + result.blockHeight_ = blockHeight_; + result.gitCommit_ = gitCommit_; + result.branch_ = branch_; + result.buildDate_ = buildDate_; + result.buildUser_ = buildUser_; + result.estimatedHeight_ = estimatedHeight_; + result.piratedBuild_ = piratedBuild_; + result.piratedSubversion_ = piratedSubversion_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.Service.LightdInfo) { + return mergeFrom((cash.z.wallet.sdk.rpc.Service.LightdInfo)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.Service.LightdInfo other) { + if (other == cash.z.wallet.sdk.rpc.Service.LightdInfo.getDefaultInstance()) return this; + if (!other.getVersion().isEmpty()) { + version_ = other.version_; + onChanged(); + } + if (!other.getVendor().isEmpty()) { + vendor_ = other.vendor_; + onChanged(); + } + if (other.getTaddrSupport() != false) { + setTaddrSupport(other.getTaddrSupport()); + } + if (!other.getChainName().isEmpty()) { + chainName_ = other.chainName_; + onChanged(); + } + if (other.getSaplingActivationHeight() != 0L) { + setSaplingActivationHeight(other.getSaplingActivationHeight()); + } + if (!other.getConsensusBranchId().isEmpty()) { + consensusBranchId_ = other.consensusBranchId_; + onChanged(); + } + if (other.getBlockHeight() != 0L) { + setBlockHeight(other.getBlockHeight()); + } + if (!other.getGitCommit().isEmpty()) { + gitCommit_ = other.gitCommit_; + onChanged(); + } + if (!other.getBranch().isEmpty()) { + branch_ = other.branch_; + onChanged(); + } + if (!other.getBuildDate().isEmpty()) { + buildDate_ = other.buildDate_; + onChanged(); + } + if (!other.getBuildUser().isEmpty()) { + buildUser_ = other.buildUser_; + onChanged(); + } + if (other.getEstimatedHeight() != 0L) { + setEstimatedHeight(other.getEstimatedHeight()); + } + if (!other.getPiratedBuild().isEmpty()) { + piratedBuild_ = other.piratedBuild_; + onChanged(); + } + if (!other.getPiratedSubversion().isEmpty()) { + piratedSubversion_ = other.piratedSubversion_; + onChanged(); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.Service.LightdInfo parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.Service.LightdInfo) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private java.lang.Object version_ = ""; + /** + * string version = 1; + * @return The version. + */ + public java.lang.String getVersion() { + java.lang.Object ref = version_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + version_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * string version = 1; + * @return The bytes for version. + */ + public com.google.protobuf.ByteString + getVersionBytes() { + java.lang.Object ref = version_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + version_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string version = 1; + * @param value The version to set. + * @return This builder for chaining. + */ + public Builder setVersion( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + version_ = value; + onChanged(); + return this; + } + /** + * string version = 1; + * @return This builder for chaining. + */ + public Builder clearVersion() { + + version_ = getDefaultInstance().getVersion(); + onChanged(); + return this; + } + /** + * string version = 1; + * @param value The bytes for version to set. + * @return This builder for chaining. + */ + public Builder setVersionBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + version_ = value; + onChanged(); + return this; + } + + private java.lang.Object vendor_ = ""; + /** + * string vendor = 2; + * @return The vendor. + */ + public java.lang.String getVendor() { + java.lang.Object ref = vendor_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + vendor_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * string vendor = 2; + * @return The bytes for vendor. + */ + public com.google.protobuf.ByteString + getVendorBytes() { + java.lang.Object ref = vendor_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + vendor_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string vendor = 2; + * @param value The vendor to set. + * @return This builder for chaining. + */ + public Builder setVendor( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + vendor_ = value; + onChanged(); + return this; + } + /** + * string vendor = 2; + * @return This builder for chaining. + */ + public Builder clearVendor() { + + vendor_ = getDefaultInstance().getVendor(); + onChanged(); + return this; + } + /** + * string vendor = 2; + * @param value The bytes for vendor to set. + * @return This builder for chaining. + */ + public Builder setVendorBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + vendor_ = value; + onChanged(); + return this; + } + + private boolean taddrSupport_ ; + /** + *
+       * true
+       * 
+ * + * bool taddrSupport = 3; + * @return The taddrSupport. + */ + @java.lang.Override + public boolean getTaddrSupport() { + return taddrSupport_; + } + /** + *
+       * true
+       * 
+ * + * bool taddrSupport = 3; + * @param value The taddrSupport to set. + * @return This builder for chaining. + */ + public Builder setTaddrSupport(boolean value) { + + taddrSupport_ = value; + onChanged(); + return this; + } + /** + *
+       * true
+       * 
+ * + * bool taddrSupport = 3; + * @return This builder for chaining. + */ + public Builder clearTaddrSupport() { + + taddrSupport_ = false; + onChanged(); + return this; + } + + private java.lang.Object chainName_ = ""; + /** + *
+       * either "main" or "test"
+       * 
+ * + * string chainName = 4; + * @return The chainName. + */ + public java.lang.String getChainName() { + java.lang.Object ref = chainName_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + chainName_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + *
+       * either "main" or "test"
+       * 
+ * + * string chainName = 4; + * @return The bytes for chainName. + */ + public com.google.protobuf.ByteString + getChainNameBytes() { + java.lang.Object ref = chainName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + chainName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + *
+       * either "main" or "test"
+       * 
+ * + * string chainName = 4; + * @param value The chainName to set. + * @return This builder for chaining. + */ + public Builder setChainName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + chainName_ = value; + onChanged(); + return this; + } + /** + *
+       * either "main" or "test"
+       * 
+ * + * string chainName = 4; + * @return This builder for chaining. + */ + public Builder clearChainName() { + + chainName_ = getDefaultInstance().getChainName(); + onChanged(); + return this; + } + /** + *
+       * either "main" or "test"
+       * 
+ * + * string chainName = 4; + * @param value The bytes for chainName to set. + * @return This builder for chaining. + */ + public Builder setChainNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + chainName_ = value; + onChanged(); + return this; + } + + private long saplingActivationHeight_ ; + /** + *
+       * depends on mainnet or testnet
+       * 
+ * + * uint64 saplingActivationHeight = 5; + * @return The saplingActivationHeight. + */ + @java.lang.Override + public long getSaplingActivationHeight() { + return saplingActivationHeight_; + } + /** + *
+       * depends on mainnet or testnet
+       * 
+ * + * uint64 saplingActivationHeight = 5; + * @param value The saplingActivationHeight to set. + * @return This builder for chaining. + */ + public Builder setSaplingActivationHeight(long value) { + + saplingActivationHeight_ = value; + onChanged(); + return this; + } + /** + *
+       * depends on mainnet or testnet
+       * 
+ * + * uint64 saplingActivationHeight = 5; + * @return This builder for chaining. + */ + public Builder clearSaplingActivationHeight() { + + saplingActivationHeight_ = 0L; + onChanged(); + return this; + } + + private java.lang.Object consensusBranchId_ = ""; + /** + *
+       * protocol identifier, see consensus/upgrades.cpp
+       * 
+ * + * string consensusBranchId = 6; + * @return The consensusBranchId. + */ + public java.lang.String getConsensusBranchId() { + java.lang.Object ref = consensusBranchId_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + consensusBranchId_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + *
+       * protocol identifier, see consensus/upgrades.cpp
+       * 
+ * + * string consensusBranchId = 6; + * @return The bytes for consensusBranchId. + */ + public com.google.protobuf.ByteString + getConsensusBranchIdBytes() { + java.lang.Object ref = consensusBranchId_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + consensusBranchId_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + *
+       * protocol identifier, see consensus/upgrades.cpp
+       * 
+ * + * string consensusBranchId = 6; + * @param value The consensusBranchId to set. + * @return This builder for chaining. + */ + public Builder setConsensusBranchId( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + consensusBranchId_ = value; + onChanged(); + return this; + } + /** + *
+       * protocol identifier, see consensus/upgrades.cpp
+       * 
+ * + * string consensusBranchId = 6; + * @return This builder for chaining. + */ + public Builder clearConsensusBranchId() { + + consensusBranchId_ = getDefaultInstance().getConsensusBranchId(); + onChanged(); + return this; + } + /** + *
+       * protocol identifier, see consensus/upgrades.cpp
+       * 
+ * + * string consensusBranchId = 6; + * @param value The bytes for consensusBranchId to set. + * @return This builder for chaining. + */ + public Builder setConsensusBranchIdBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + consensusBranchId_ = value; + onChanged(); + return this; + } + + private long blockHeight_ ; + /** + *
+       * latest block on the best chain
+       * 
+ * + * uint64 blockHeight = 7; + * @return The blockHeight. + */ + @java.lang.Override + public long getBlockHeight() { + return blockHeight_; + } + /** + *
+       * latest block on the best chain
+       * 
+ * + * uint64 blockHeight = 7; + * @param value The blockHeight to set. + * @return This builder for chaining. + */ + public Builder setBlockHeight(long value) { + + blockHeight_ = value; + onChanged(); + return this; + } + /** + *
+       * latest block on the best chain
+       * 
+ * + * uint64 blockHeight = 7; + * @return This builder for chaining. + */ + public Builder clearBlockHeight() { + + blockHeight_ = 0L; + onChanged(); + return this; + } + + private java.lang.Object gitCommit_ = ""; + /** + * string gitCommit = 8; + * @return The gitCommit. + */ + public java.lang.String getGitCommit() { + java.lang.Object ref = gitCommit_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + gitCommit_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * string gitCommit = 8; + * @return The bytes for gitCommit. + */ + public com.google.protobuf.ByteString + getGitCommitBytes() { + java.lang.Object ref = gitCommit_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + gitCommit_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string gitCommit = 8; + * @param value The gitCommit to set. + * @return This builder for chaining. + */ + public Builder setGitCommit( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + gitCommit_ = value; + onChanged(); + return this; + } + /** + * string gitCommit = 8; + * @return This builder for chaining. + */ + public Builder clearGitCommit() { + + gitCommit_ = getDefaultInstance().getGitCommit(); + onChanged(); + return this; + } + /** + * string gitCommit = 8; + * @param value The bytes for gitCommit to set. + * @return This builder for chaining. + */ + public Builder setGitCommitBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + gitCommit_ = value; + onChanged(); + return this; + } + + private java.lang.Object branch_ = ""; + /** + * string branch = 9; + * @return The branch. + */ + public java.lang.String getBranch() { + java.lang.Object ref = branch_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + branch_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * string branch = 9; + * @return The bytes for branch. + */ + public com.google.protobuf.ByteString + getBranchBytes() { + java.lang.Object ref = branch_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + branch_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string branch = 9; + * @param value The branch to set. + * @return This builder for chaining. + */ + public Builder setBranch( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + branch_ = value; + onChanged(); + return this; + } + /** + * string branch = 9; + * @return This builder for chaining. + */ + public Builder clearBranch() { + + branch_ = getDefaultInstance().getBranch(); + onChanged(); + return this; + } + /** + * string branch = 9; + * @param value The bytes for branch to set. + * @return This builder for chaining. + */ + public Builder setBranchBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + branch_ = value; + onChanged(); + return this; + } + + private java.lang.Object buildDate_ = ""; + /** + * string buildDate = 10; + * @return The buildDate. + */ + public java.lang.String getBuildDate() { + java.lang.Object ref = buildDate_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + buildDate_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * string buildDate = 10; + * @return The bytes for buildDate. + */ + public com.google.protobuf.ByteString + getBuildDateBytes() { + java.lang.Object ref = buildDate_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + buildDate_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string buildDate = 10; + * @param value The buildDate to set. + * @return This builder for chaining. + */ + public Builder setBuildDate( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + buildDate_ = value; + onChanged(); + return this; + } + /** + * string buildDate = 10; + * @return This builder for chaining. + */ + public Builder clearBuildDate() { + + buildDate_ = getDefaultInstance().getBuildDate(); + onChanged(); + return this; + } + /** + * string buildDate = 10; + * @param value The bytes for buildDate to set. + * @return This builder for chaining. + */ + public Builder setBuildDateBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + buildDate_ = value; + onChanged(); + return this; + } + + private java.lang.Object buildUser_ = ""; + /** + * string buildUser = 11; + * @return The buildUser. + */ + public java.lang.String getBuildUser() { + java.lang.Object ref = buildUser_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + buildUser_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * string buildUser = 11; + * @return The bytes for buildUser. + */ + public com.google.protobuf.ByteString + getBuildUserBytes() { + java.lang.Object ref = buildUser_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + buildUser_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string buildUser = 11; + * @param value The buildUser to set. + * @return This builder for chaining. + */ + public Builder setBuildUser( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + buildUser_ = value; + onChanged(); + return this; + } + /** + * string buildUser = 11; + * @return This builder for chaining. + */ + public Builder clearBuildUser() { + + buildUser_ = getDefaultInstance().getBuildUser(); + onChanged(); + return this; + } + /** + * string buildUser = 11; + * @param value The bytes for buildUser to set. + * @return This builder for chaining. + */ + public Builder setBuildUserBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + buildUser_ = value; + onChanged(); + return this; + } + + private long estimatedHeight_ ; + /** + *
+       * less than tip height if pirated is syncing
+       * 
+ * + * uint64 estimatedHeight = 12; + * @return The estimatedHeight. + */ + @java.lang.Override + public long getEstimatedHeight() { + return estimatedHeight_; + } + /** + *
+       * less than tip height if pirated is syncing
+       * 
+ * + * uint64 estimatedHeight = 12; + * @param value The estimatedHeight to set. + * @return This builder for chaining. + */ + public Builder setEstimatedHeight(long value) { + + estimatedHeight_ = value; + onChanged(); + return this; + } + /** + *
+       * less than tip height if pirated is syncing
+       * 
+ * + * uint64 estimatedHeight = 12; + * @return This builder for chaining. + */ + public Builder clearEstimatedHeight() { + + estimatedHeight_ = 0L; + onChanged(); + return this; + } + + private java.lang.Object piratedBuild_ = ""; + /** + *
+       * example: "v4.1.1-877212414"
+       * 
+ * + * string piratedBuild = 13; + * @return The piratedBuild. + */ + public java.lang.String getPiratedBuild() { + java.lang.Object ref = piratedBuild_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + piratedBuild_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + *
+       * example: "v4.1.1-877212414"
+       * 
+ * + * string piratedBuild = 13; + * @return The bytes for piratedBuild. + */ + public com.google.protobuf.ByteString + getPiratedBuildBytes() { + java.lang.Object ref = piratedBuild_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + piratedBuild_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + *
+       * example: "v4.1.1-877212414"
+       * 
+ * + * string piratedBuild = 13; + * @param value The piratedBuild to set. + * @return This builder for chaining. + */ + public Builder setPiratedBuild( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + piratedBuild_ = value; + onChanged(); + return this; + } + /** + *
+       * example: "v4.1.1-877212414"
+       * 
+ * + * string piratedBuild = 13; + * @return This builder for chaining. + */ + public Builder clearPiratedBuild() { + + piratedBuild_ = getDefaultInstance().getPiratedBuild(); + onChanged(); + return this; + } + /** + *
+       * example: "v4.1.1-877212414"
+       * 
+ * + * string piratedBuild = 13; + * @param value The bytes for piratedBuild to set. + * @return This builder for chaining. + */ + public Builder setPiratedBuildBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + piratedBuild_ = value; + onChanged(); + return this; + } + + private java.lang.Object piratedSubversion_ = ""; + /** + *
+       * example: "/MagicBean:4.1.1/"
+       * 
+ * + * string piratedSubversion = 14; + * @return The piratedSubversion. + */ + public java.lang.String getPiratedSubversion() { + java.lang.Object ref = piratedSubversion_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + piratedSubversion_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + *
+       * example: "/MagicBean:4.1.1/"
+       * 
+ * + * string piratedSubversion = 14; + * @return The bytes for piratedSubversion. + */ + public com.google.protobuf.ByteString + getPiratedSubversionBytes() { + java.lang.Object ref = piratedSubversion_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + piratedSubversion_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + *
+       * example: "/MagicBean:4.1.1/"
+       * 
+ * + * string piratedSubversion = 14; + * @param value The piratedSubversion to set. + * @return This builder for chaining. + */ + public Builder setPiratedSubversion( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + piratedSubversion_ = value; + onChanged(); + return this; + } + /** + *
+       * example: "/MagicBean:4.1.1/"
+       * 
+ * + * string piratedSubversion = 14; + * @return This builder for chaining. + */ + public Builder clearPiratedSubversion() { + + piratedSubversion_ = getDefaultInstance().getPiratedSubversion(); + onChanged(); + return this; + } + /** + *
+       * example: "/MagicBean:4.1.1/"
+       * 
+ * + * string piratedSubversion = 14; + * @param value The bytes for piratedSubversion to set. + * @return This builder for chaining. + */ + public Builder setPiratedSubversionBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + piratedSubversion_ = value; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.LightdInfo) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.LightdInfo) + private static final cash.z.wallet.sdk.rpc.Service.LightdInfo DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.Service.LightdInfo(); + } + + public static cash.z.wallet.sdk.rpc.Service.LightdInfo getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public LightdInfo parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new LightdInfo(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.LightdInfo getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface TransparentAddressBlockFilterOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.TransparentAddressBlockFilter) + com.google.protobuf.MessageOrBuilder { + + /** + *
+     * t-address
+     * 
+ * + * string address = 1; + * @return The address. + */ + java.lang.String getAddress(); + /** + *
+     * t-address
+     * 
+ * + * string address = 1; + * @return The bytes for address. + */ + com.google.protobuf.ByteString + getAddressBytes(); + + /** + *
+     * start, end heights
+     * 
+ * + * .cash.z.wallet.sdk.rpc.BlockRange range = 2; + * @return Whether the range field is set. + */ + boolean hasRange(); + /** + *
+     * start, end heights
+     * 
+ * + * .cash.z.wallet.sdk.rpc.BlockRange range = 2; + * @return The range. + */ + cash.z.wallet.sdk.rpc.Service.BlockRange getRange(); + /** + *
+     * start, end heights
+     * 
+ * + * .cash.z.wallet.sdk.rpc.BlockRange range = 2; + */ + cash.z.wallet.sdk.rpc.Service.BlockRangeOrBuilder getRangeOrBuilder(); + } + /** + *
+   * TransparentAddressBlockFilter restricts the results to the given address
+   * or block range.
+   * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.TransparentAddressBlockFilter} + */ + public static final class TransparentAddressBlockFilter extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.TransparentAddressBlockFilter) + TransparentAddressBlockFilterOrBuilder { + private static final long serialVersionUID = 0L; + // Use TransparentAddressBlockFilter.newBuilder() to construct. + private TransparentAddressBlockFilter(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private TransparentAddressBlockFilter() { + address_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new TransparentAddressBlockFilter(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private TransparentAddressBlockFilter( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + java.lang.String s = input.readStringRequireUtf8(); + + address_ = s; + break; + } + case 18: { + cash.z.wallet.sdk.rpc.Service.BlockRange.Builder subBuilder = null; + if (range_ != null) { + subBuilder = range_.toBuilder(); + } + range_ = input.readMessage(cash.z.wallet.sdk.rpc.Service.BlockRange.parser(), extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(range_); + range_ = subBuilder.buildPartial(); + } + + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_TransparentAddressBlockFilter_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_TransparentAddressBlockFilter_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter.class, cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter.Builder.class); + } + + public static final int ADDRESS_FIELD_NUMBER = 1; + private volatile java.lang.Object address_; + /** + *
+     * t-address
+     * 
+ * + * string address = 1; + * @return The address. + */ + @java.lang.Override + public java.lang.String getAddress() { + java.lang.Object ref = address_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + address_ = s; + return s; + } + } + /** + *
+     * t-address
+     * 
+ * + * string address = 1; + * @return The bytes for address. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getAddressBytes() { + java.lang.Object ref = address_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + address_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int RANGE_FIELD_NUMBER = 2; + private cash.z.wallet.sdk.rpc.Service.BlockRange range_; + /** + *
+     * start, end heights
+     * 
+ * + * .cash.z.wallet.sdk.rpc.BlockRange range = 2; + * @return Whether the range field is set. + */ + @java.lang.Override + public boolean hasRange() { + return range_ != null; + } + /** + *
+     * start, end heights
+     * 
+ * + * .cash.z.wallet.sdk.rpc.BlockRange range = 2; + * @return The range. + */ + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.BlockRange getRange() { + return range_ == null ? cash.z.wallet.sdk.rpc.Service.BlockRange.getDefaultInstance() : range_; + } + /** + *
+     * start, end heights
+     * 
+ * + * .cash.z.wallet.sdk.rpc.BlockRange range = 2; + */ + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.BlockRangeOrBuilder getRangeOrBuilder() { + return getRange(); + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(address_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, address_); + } + if (range_ != null) { + output.writeMessage(2, getRange()); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(address_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, address_); + } + if (range_ != null) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, getRange()); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter other = (cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter) obj; + + if (!getAddress() + .equals(other.getAddress())) return false; + if (hasRange() != other.hasRange()) return false; + if (hasRange()) { + if (!getRange() + .equals(other.getRange())) return false; + } + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + ADDRESS_FIELD_NUMBER; + hash = (53 * hash) + getAddress().hashCode(); + if (hasRange()) { + hash = (37 * hash) + RANGE_FIELD_NUMBER; + hash = (53 * hash) + getRange().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * TransparentAddressBlockFilter restricts the results to the given address
+     * or block range.
+     * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.TransparentAddressBlockFilter} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.TransparentAddressBlockFilter) + cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilterOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_TransparentAddressBlockFilter_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_TransparentAddressBlockFilter_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter.class, cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + address_ = ""; + + if (rangeBuilder_ == null) { + range_ = null; + } else { + range_ = null; + rangeBuilder_ = null; + } + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_TransparentAddressBlockFilter_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter build() { + cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter buildPartial() { + cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter result = new cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter(this); + result.address_ = address_; + if (rangeBuilder_ == null) { + result.range_ = range_; + } else { + result.range_ = rangeBuilder_.build(); + } + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter) { + return mergeFrom((cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter other) { + if (other == cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter.getDefaultInstance()) return this; + if (!other.getAddress().isEmpty()) { + address_ = other.address_; + onChanged(); + } + if (other.hasRange()) { + mergeRange(other.getRange()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private java.lang.Object address_ = ""; + /** + *
+       * t-address
+       * 
+ * + * string address = 1; + * @return The address. + */ + public java.lang.String getAddress() { + java.lang.Object ref = address_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + address_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + *
+       * t-address
+       * 
+ * + * string address = 1; + * @return The bytes for address. + */ + public com.google.protobuf.ByteString + getAddressBytes() { + java.lang.Object ref = address_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + address_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + *
+       * t-address
+       * 
+ * + * string address = 1; + * @param value The address to set. + * @return This builder for chaining. + */ + public Builder setAddress( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + address_ = value; + onChanged(); + return this; + } + /** + *
+       * t-address
+       * 
+ * + * string address = 1; + * @return This builder for chaining. + */ + public Builder clearAddress() { + + address_ = getDefaultInstance().getAddress(); + onChanged(); + return this; + } + /** + *
+       * t-address
+       * 
+ * + * string address = 1; + * @param value The bytes for address to set. + * @return This builder for chaining. + */ + public Builder setAddressBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + address_ = value; + onChanged(); + return this; + } + + private cash.z.wallet.sdk.rpc.Service.BlockRange range_; + private com.google.protobuf.SingleFieldBuilderV3< + cash.z.wallet.sdk.rpc.Service.BlockRange, cash.z.wallet.sdk.rpc.Service.BlockRange.Builder, cash.z.wallet.sdk.rpc.Service.BlockRangeOrBuilder> rangeBuilder_; + /** + *
+       * start, end heights
+       * 
+ * + * .cash.z.wallet.sdk.rpc.BlockRange range = 2; + * @return Whether the range field is set. + */ + public boolean hasRange() { + return rangeBuilder_ != null || range_ != null; + } + /** + *
+       * start, end heights
+       * 
+ * + * .cash.z.wallet.sdk.rpc.BlockRange range = 2; + * @return The range. + */ + public cash.z.wallet.sdk.rpc.Service.BlockRange getRange() { + if (rangeBuilder_ == null) { + return range_ == null ? cash.z.wallet.sdk.rpc.Service.BlockRange.getDefaultInstance() : range_; + } else { + return rangeBuilder_.getMessage(); + } + } + /** + *
+       * start, end heights
+       * 
+ * + * .cash.z.wallet.sdk.rpc.BlockRange range = 2; + */ + public Builder setRange(cash.z.wallet.sdk.rpc.Service.BlockRange value) { + if (rangeBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + range_ = value; + onChanged(); + } else { + rangeBuilder_.setMessage(value); + } + + return this; + } + /** + *
+       * start, end heights
+       * 
+ * + * .cash.z.wallet.sdk.rpc.BlockRange range = 2; + */ + public Builder setRange( + cash.z.wallet.sdk.rpc.Service.BlockRange.Builder builderForValue) { + if (rangeBuilder_ == null) { + range_ = builderForValue.build(); + onChanged(); + } else { + rangeBuilder_.setMessage(builderForValue.build()); + } + + return this; + } + /** + *
+       * start, end heights
+       * 
+ * + * .cash.z.wallet.sdk.rpc.BlockRange range = 2; + */ + public Builder mergeRange(cash.z.wallet.sdk.rpc.Service.BlockRange value) { + if (rangeBuilder_ == null) { + if (range_ != null) { + range_ = + cash.z.wallet.sdk.rpc.Service.BlockRange.newBuilder(range_).mergeFrom(value).buildPartial(); + } else { + range_ = value; + } + onChanged(); + } else { + rangeBuilder_.mergeFrom(value); + } + + return this; + } + /** + *
+       * start, end heights
+       * 
+ * + * .cash.z.wallet.sdk.rpc.BlockRange range = 2; + */ + public Builder clearRange() { + if (rangeBuilder_ == null) { + range_ = null; + onChanged(); + } else { + range_ = null; + rangeBuilder_ = null; + } + + return this; + } + /** + *
+       * start, end heights
+       * 
+ * + * .cash.z.wallet.sdk.rpc.BlockRange range = 2; + */ + public cash.z.wallet.sdk.rpc.Service.BlockRange.Builder getRangeBuilder() { + + onChanged(); + return getRangeFieldBuilder().getBuilder(); + } + /** + *
+       * start, end heights
+       * 
+ * + * .cash.z.wallet.sdk.rpc.BlockRange range = 2; + */ + public cash.z.wallet.sdk.rpc.Service.BlockRangeOrBuilder getRangeOrBuilder() { + if (rangeBuilder_ != null) { + return rangeBuilder_.getMessageOrBuilder(); + } else { + return range_ == null ? + cash.z.wallet.sdk.rpc.Service.BlockRange.getDefaultInstance() : range_; + } + } + /** + *
+       * start, end heights
+       * 
+ * + * .cash.z.wallet.sdk.rpc.BlockRange range = 2; + */ + private com.google.protobuf.SingleFieldBuilderV3< + cash.z.wallet.sdk.rpc.Service.BlockRange, cash.z.wallet.sdk.rpc.Service.BlockRange.Builder, cash.z.wallet.sdk.rpc.Service.BlockRangeOrBuilder> + getRangeFieldBuilder() { + if (rangeBuilder_ == null) { + rangeBuilder_ = new com.google.protobuf.SingleFieldBuilderV3< + cash.z.wallet.sdk.rpc.Service.BlockRange, cash.z.wallet.sdk.rpc.Service.BlockRange.Builder, cash.z.wallet.sdk.rpc.Service.BlockRangeOrBuilder>( + getRange(), + getParentForChildren(), + isClean()); + range_ = null; + } + return rangeBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.TransparentAddressBlockFilter) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.TransparentAddressBlockFilter) + private static final cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter(); + } + + public static cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public TransparentAddressBlockFilter parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new TransparentAddressBlockFilter(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.TransparentAddressBlockFilter getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface DurationOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.Duration) + com.google.protobuf.MessageOrBuilder { + + /** + * int64 intervalUs = 1; + * @return The intervalUs. + */ + long getIntervalUs(); + } + /** + *
+   * Duration is currently used only for testing, so that the Ping rpc
+   * can simulate a delay, to create many simultaneous connections. Units
+   * are microseconds.
+   * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.Duration} + */ + public static final class Duration extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.Duration) + DurationOrBuilder { + private static final long serialVersionUID = 0L; + // Use Duration.newBuilder() to construct. + private Duration(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Duration() { + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new Duration(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Duration( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: { + + intervalUs_ = input.readInt64(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_Duration_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_Duration_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.Duration.class, cash.z.wallet.sdk.rpc.Service.Duration.Builder.class); + } + + public static final int INTERVALUS_FIELD_NUMBER = 1; + private long intervalUs_; + /** + * int64 intervalUs = 1; + * @return The intervalUs. + */ + @java.lang.Override + public long getIntervalUs() { + return intervalUs_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (intervalUs_ != 0L) { + output.writeInt64(1, intervalUs_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (intervalUs_ != 0L) { + size += com.google.protobuf.CodedOutputStream + .computeInt64Size(1, intervalUs_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.Service.Duration)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.Service.Duration other = (cash.z.wallet.sdk.rpc.Service.Duration) obj; + + if (getIntervalUs() + != other.getIntervalUs()) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + INTERVALUS_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashLong( + getIntervalUs()); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.Service.Duration parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.Duration parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.Duration parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.Duration parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.Duration parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.Duration parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.Duration parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.Duration parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.Duration parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.Duration parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.Duration parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.Duration parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.Service.Duration prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * Duration is currently used only for testing, so that the Ping rpc
+     * can simulate a delay, to create many simultaneous connections. Units
+     * are microseconds.
+     * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.Duration} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.Duration) + cash.z.wallet.sdk.rpc.Service.DurationOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_Duration_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_Duration_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.Duration.class, cash.z.wallet.sdk.rpc.Service.Duration.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.Service.Duration.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + intervalUs_ = 0L; + + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_Duration_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.Duration getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.Service.Duration.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.Duration build() { + cash.z.wallet.sdk.rpc.Service.Duration result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.Duration buildPartial() { + cash.z.wallet.sdk.rpc.Service.Duration result = new cash.z.wallet.sdk.rpc.Service.Duration(this); + result.intervalUs_ = intervalUs_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.Service.Duration) { + return mergeFrom((cash.z.wallet.sdk.rpc.Service.Duration)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.Service.Duration other) { + if (other == cash.z.wallet.sdk.rpc.Service.Duration.getDefaultInstance()) return this; + if (other.getIntervalUs() != 0L) { + setIntervalUs(other.getIntervalUs()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.Service.Duration parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.Service.Duration) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private long intervalUs_ ; + /** + * int64 intervalUs = 1; + * @return The intervalUs. + */ + @java.lang.Override + public long getIntervalUs() { + return intervalUs_; + } + /** + * int64 intervalUs = 1; + * @param value The intervalUs to set. + * @return This builder for chaining. + */ + public Builder setIntervalUs(long value) { + + intervalUs_ = value; + onChanged(); + return this; + } + /** + * int64 intervalUs = 1; + * @return This builder for chaining. + */ + public Builder clearIntervalUs() { + + intervalUs_ = 0L; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.Duration) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.Duration) + private static final cash.z.wallet.sdk.rpc.Service.Duration DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.Service.Duration(); + } + + public static cash.z.wallet.sdk.rpc.Service.Duration getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public Duration parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Duration(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.Duration getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface PingResponseOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.PingResponse) + com.google.protobuf.MessageOrBuilder { + + /** + * int64 entry = 1; + * @return The entry. + */ + long getEntry(); + + /** + * int64 exit = 2; + * @return The exit. + */ + long getExit(); + } + /** + *
+   * PingResponse is used to indicate concurrency, how many Ping rpcs
+   * are executing upon entry and upon exit (after the delay).
+   * This rpc is used for testing only.
+   * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.PingResponse} + */ + public static final class PingResponse extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.PingResponse) + PingResponseOrBuilder { + private static final long serialVersionUID = 0L; + // Use PingResponse.newBuilder() to construct. + private PingResponse(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private PingResponse() { + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new PingResponse(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private PingResponse( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: { + + entry_ = input.readInt64(); + break; + } + case 16: { + + exit_ = input.readInt64(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_PingResponse_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_PingResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.PingResponse.class, cash.z.wallet.sdk.rpc.Service.PingResponse.Builder.class); + } + + public static final int ENTRY_FIELD_NUMBER = 1; + private long entry_; + /** + * int64 entry = 1; + * @return The entry. + */ + @java.lang.Override + public long getEntry() { + return entry_; + } + + public static final int EXIT_FIELD_NUMBER = 2; + private long exit_; + /** + * int64 exit = 2; + * @return The exit. + */ + @java.lang.Override + public long getExit() { + return exit_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (entry_ != 0L) { + output.writeInt64(1, entry_); + } + if (exit_ != 0L) { + output.writeInt64(2, exit_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (entry_ != 0L) { + size += com.google.protobuf.CodedOutputStream + .computeInt64Size(1, entry_); + } + if (exit_ != 0L) { + size += com.google.protobuf.CodedOutputStream + .computeInt64Size(2, exit_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.Service.PingResponse)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.Service.PingResponse other = (cash.z.wallet.sdk.rpc.Service.PingResponse) obj; + + if (getEntry() + != other.getEntry()) return false; + if (getExit() + != other.getExit()) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + ENTRY_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashLong( + getEntry()); + hash = (37 * hash) + EXIT_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashLong( + getExit()); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.Service.PingResponse parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.PingResponse parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.PingResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.PingResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.PingResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.PingResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.PingResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.PingResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.PingResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.PingResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.PingResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.PingResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.Service.PingResponse prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * PingResponse is used to indicate concurrency, how many Ping rpcs
+     * are executing upon entry and upon exit (after the delay).
+     * This rpc is used for testing only.
+     * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.PingResponse} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.PingResponse) + cash.z.wallet.sdk.rpc.Service.PingResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_PingResponse_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_PingResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.PingResponse.class, cash.z.wallet.sdk.rpc.Service.PingResponse.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.Service.PingResponse.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + entry_ = 0L; + + exit_ = 0L; + + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_PingResponse_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.PingResponse getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.Service.PingResponse.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.PingResponse build() { + cash.z.wallet.sdk.rpc.Service.PingResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.PingResponse buildPartial() { + cash.z.wallet.sdk.rpc.Service.PingResponse result = new cash.z.wallet.sdk.rpc.Service.PingResponse(this); + result.entry_ = entry_; + result.exit_ = exit_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.Service.PingResponse) { + return mergeFrom((cash.z.wallet.sdk.rpc.Service.PingResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.Service.PingResponse other) { + if (other == cash.z.wallet.sdk.rpc.Service.PingResponse.getDefaultInstance()) return this; + if (other.getEntry() != 0L) { + setEntry(other.getEntry()); + } + if (other.getExit() != 0L) { + setExit(other.getExit()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.Service.PingResponse parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.Service.PingResponse) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private long entry_ ; + /** + * int64 entry = 1; + * @return The entry. + */ + @java.lang.Override + public long getEntry() { + return entry_; + } + /** + * int64 entry = 1; + * @param value The entry to set. + * @return This builder for chaining. + */ + public Builder setEntry(long value) { + + entry_ = value; + onChanged(); + return this; + } + /** + * int64 entry = 1; + * @return This builder for chaining. + */ + public Builder clearEntry() { + + entry_ = 0L; + onChanged(); + return this; + } + + private long exit_ ; + /** + * int64 exit = 2; + * @return The exit. + */ + @java.lang.Override + public long getExit() { + return exit_; + } + /** + * int64 exit = 2; + * @param value The exit to set. + * @return This builder for chaining. + */ + public Builder setExit(long value) { + + exit_ = value; + onChanged(); + return this; + } + /** + * int64 exit = 2; + * @return This builder for chaining. + */ + public Builder clearExit() { + + exit_ = 0L; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.PingResponse) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.PingResponse) + private static final cash.z.wallet.sdk.rpc.Service.PingResponse DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.Service.PingResponse(); + } + + public static cash.z.wallet.sdk.rpc.Service.PingResponse getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public PingResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new PingResponse(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.PingResponse getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface AddressOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.Address) + com.google.protobuf.MessageOrBuilder { + + /** + * string address = 1; + * @return The address. + */ + java.lang.String getAddress(); + /** + * string address = 1; + * @return The bytes for address. + */ + com.google.protobuf.ByteString + getAddressBytes(); + } + /** + * Protobuf type {@code cash.z.wallet.sdk.rpc.Address} + */ + public static final class Address extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.Address) + AddressOrBuilder { + private static final long serialVersionUID = 0L; + // Use Address.newBuilder() to construct. + private Address(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Address() { + address_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new Address(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Address( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + java.lang.String s = input.readStringRequireUtf8(); + + address_ = s; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_Address_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_Address_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.Address.class, cash.z.wallet.sdk.rpc.Service.Address.Builder.class); + } + + public static final int ADDRESS_FIELD_NUMBER = 1; + private volatile java.lang.Object address_; + /** + * string address = 1; + * @return The address. + */ + @java.lang.Override + public java.lang.String getAddress() { + java.lang.Object ref = address_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + address_ = s; + return s; + } + } + /** + * string address = 1; + * @return The bytes for address. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getAddressBytes() { + java.lang.Object ref = address_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + address_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(address_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, address_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(address_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, address_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.Service.Address)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.Service.Address other = (cash.z.wallet.sdk.rpc.Service.Address) obj; + + if (!getAddress() + .equals(other.getAddress())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + ADDRESS_FIELD_NUMBER; + hash = (53 * hash) + getAddress().hashCode(); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.Service.Address parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.Address parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.Address parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.Address parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.Address parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.Address parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.Address parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.Address parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.Address parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.Address parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.Address parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.Address parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.Service.Address prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code cash.z.wallet.sdk.rpc.Address} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.Address) + cash.z.wallet.sdk.rpc.Service.AddressOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_Address_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_Address_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.Address.class, cash.z.wallet.sdk.rpc.Service.Address.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.Service.Address.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + address_ = ""; + + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_Address_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.Address getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.Service.Address.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.Address build() { + cash.z.wallet.sdk.rpc.Service.Address result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.Address buildPartial() { + cash.z.wallet.sdk.rpc.Service.Address result = new cash.z.wallet.sdk.rpc.Service.Address(this); + result.address_ = address_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.Service.Address) { + return mergeFrom((cash.z.wallet.sdk.rpc.Service.Address)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.Service.Address other) { + if (other == cash.z.wallet.sdk.rpc.Service.Address.getDefaultInstance()) return this; + if (!other.getAddress().isEmpty()) { + address_ = other.address_; + onChanged(); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.Service.Address parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.Service.Address) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private java.lang.Object address_ = ""; + /** + * string address = 1; + * @return The address. + */ + public java.lang.String getAddress() { + java.lang.Object ref = address_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + address_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * string address = 1; + * @return The bytes for address. + */ + public com.google.protobuf.ByteString + getAddressBytes() { + java.lang.Object ref = address_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + address_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string address = 1; + * @param value The address to set. + * @return This builder for chaining. + */ + public Builder setAddress( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + address_ = value; + onChanged(); + return this; + } + /** + * string address = 1; + * @return This builder for chaining. + */ + public Builder clearAddress() { + + address_ = getDefaultInstance().getAddress(); + onChanged(); + return this; + } + /** + * string address = 1; + * @param value The bytes for address to set. + * @return This builder for chaining. + */ + public Builder setAddressBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + address_ = value; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.Address) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.Address) + private static final cash.z.wallet.sdk.rpc.Service.Address DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.Service.Address(); + } + + public static cash.z.wallet.sdk.rpc.Service.Address getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser
+ PARSER = new com.google.protobuf.AbstractParser
() { + @java.lang.Override + public Address parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Address(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser
parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser
getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.Address getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface AddressListOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.AddressList) + com.google.protobuf.MessageOrBuilder { + + /** + * repeated string addresses = 1; + * @return A list containing the addresses. + */ + java.util.List + getAddressesList(); + /** + * repeated string addresses = 1; + * @return The count of addresses. + */ + int getAddressesCount(); + /** + * repeated string addresses = 1; + * @param index The index of the element to return. + * @return The addresses at the given index. + */ + java.lang.String getAddresses(int index); + /** + * repeated string addresses = 1; + * @param index The index of the value to return. + * @return The bytes of the addresses at the given index. + */ + com.google.protobuf.ByteString + getAddressesBytes(int index); + } + /** + * Protobuf type {@code cash.z.wallet.sdk.rpc.AddressList} + */ + public static final class AddressList extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.AddressList) + AddressListOrBuilder { + private static final long serialVersionUID = 0L; + // Use AddressList.newBuilder() to construct. + private AddressList(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private AddressList() { + addresses_ = com.google.protobuf.LazyStringArrayList.EMPTY; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new AddressList(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private AddressList( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + java.lang.String s = input.readStringRequireUtf8(); + if (!((mutable_bitField0_ & 0x00000001) != 0)) { + addresses_ = new com.google.protobuf.LazyStringArrayList(); + mutable_bitField0_ |= 0x00000001; + } + addresses_.add(s); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) != 0)) { + addresses_ = addresses_.getUnmodifiableView(); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_AddressList_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_AddressList_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.AddressList.class, cash.z.wallet.sdk.rpc.Service.AddressList.Builder.class); + } + + public static final int ADDRESSES_FIELD_NUMBER = 1; + private com.google.protobuf.LazyStringList addresses_; + /** + * repeated string addresses = 1; + * @return A list containing the addresses. + */ + public com.google.protobuf.ProtocolStringList + getAddressesList() { + return addresses_; + } + /** + * repeated string addresses = 1; + * @return The count of addresses. + */ + public int getAddressesCount() { + return addresses_.size(); + } + /** + * repeated string addresses = 1; + * @param index The index of the element to return. + * @return The addresses at the given index. + */ + public java.lang.String getAddresses(int index) { + return addresses_.get(index); + } + /** + * repeated string addresses = 1; + * @param index The index of the value to return. + * @return The bytes of the addresses at the given index. + */ + public com.google.protobuf.ByteString + getAddressesBytes(int index) { + return addresses_.getByteString(index); + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + for (int i = 0; i < addresses_.size(); i++) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, addresses_.getRaw(i)); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + { + int dataSize = 0; + for (int i = 0; i < addresses_.size(); i++) { + dataSize += computeStringSizeNoTag(addresses_.getRaw(i)); + } + size += dataSize; + size += 1 * getAddressesList().size(); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.Service.AddressList)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.Service.AddressList other = (cash.z.wallet.sdk.rpc.Service.AddressList) obj; + + if (!getAddressesList() + .equals(other.getAddressesList())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (getAddressesCount() > 0) { + hash = (37 * hash) + ADDRESSES_FIELD_NUMBER; + hash = (53 * hash) + getAddressesList().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.Service.AddressList parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.AddressList parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.AddressList parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.AddressList parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.AddressList parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.AddressList parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.AddressList parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.AddressList parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.AddressList parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.AddressList parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.AddressList parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.AddressList parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.Service.AddressList prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code cash.z.wallet.sdk.rpc.AddressList} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.AddressList) + cash.z.wallet.sdk.rpc.Service.AddressListOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_AddressList_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_AddressList_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.AddressList.class, cash.z.wallet.sdk.rpc.Service.AddressList.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.Service.AddressList.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + addresses_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_AddressList_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.AddressList getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.Service.AddressList.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.AddressList build() { + cash.z.wallet.sdk.rpc.Service.AddressList result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.AddressList buildPartial() { + cash.z.wallet.sdk.rpc.Service.AddressList result = new cash.z.wallet.sdk.rpc.Service.AddressList(this); + int from_bitField0_ = bitField0_; + if (((bitField0_ & 0x00000001) != 0)) { + addresses_ = addresses_.getUnmodifiableView(); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.addresses_ = addresses_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.Service.AddressList) { + return mergeFrom((cash.z.wallet.sdk.rpc.Service.AddressList)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.Service.AddressList other) { + if (other == cash.z.wallet.sdk.rpc.Service.AddressList.getDefaultInstance()) return this; + if (!other.addresses_.isEmpty()) { + if (addresses_.isEmpty()) { + addresses_ = other.addresses_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureAddressesIsMutable(); + addresses_.addAll(other.addresses_); + } + onChanged(); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.Service.AddressList parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.Service.AddressList) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private com.google.protobuf.LazyStringList addresses_ = com.google.protobuf.LazyStringArrayList.EMPTY; + private void ensureAddressesIsMutable() { + if (!((bitField0_ & 0x00000001) != 0)) { + addresses_ = new com.google.protobuf.LazyStringArrayList(addresses_); + bitField0_ |= 0x00000001; + } + } + /** + * repeated string addresses = 1; + * @return A list containing the addresses. + */ + public com.google.protobuf.ProtocolStringList + getAddressesList() { + return addresses_.getUnmodifiableView(); + } + /** + * repeated string addresses = 1; + * @return The count of addresses. + */ + public int getAddressesCount() { + return addresses_.size(); + } + /** + * repeated string addresses = 1; + * @param index The index of the element to return. + * @return The addresses at the given index. + */ + public java.lang.String getAddresses(int index) { + return addresses_.get(index); + } + /** + * repeated string addresses = 1; + * @param index The index of the value to return. + * @return The bytes of the addresses at the given index. + */ + public com.google.protobuf.ByteString + getAddressesBytes(int index) { + return addresses_.getByteString(index); + } + /** + * repeated string addresses = 1; + * @param index The index to set the value at. + * @param value The addresses to set. + * @return This builder for chaining. + */ + public Builder setAddresses( + int index, java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureAddressesIsMutable(); + addresses_.set(index, value); + onChanged(); + return this; + } + /** + * repeated string addresses = 1; + * @param value The addresses to add. + * @return This builder for chaining. + */ + public Builder addAddresses( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureAddressesIsMutable(); + addresses_.add(value); + onChanged(); + return this; + } + /** + * repeated string addresses = 1; + * @param values The addresses to add. + * @return This builder for chaining. + */ + public Builder addAllAddresses( + java.lang.Iterable values) { + ensureAddressesIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, addresses_); + onChanged(); + return this; + } + /** + * repeated string addresses = 1; + * @return This builder for chaining. + */ + public Builder clearAddresses() { + addresses_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + return this; + } + /** + * repeated string addresses = 1; + * @param value The bytes of the addresses to add. + * @return This builder for chaining. + */ + public Builder addAddressesBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + ensureAddressesIsMutable(); + addresses_.add(value); + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.AddressList) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.AddressList) + private static final cash.z.wallet.sdk.rpc.Service.AddressList DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.Service.AddressList(); + } + + public static cash.z.wallet.sdk.rpc.Service.AddressList getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public AddressList parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new AddressList(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.AddressList getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface BalanceOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.Balance) + com.google.protobuf.MessageOrBuilder { + + /** + * int64 valueZat = 1; + * @return The valueZat. + */ + long getValueZat(); + } + /** + * Protobuf type {@code cash.z.wallet.sdk.rpc.Balance} + */ + public static final class Balance extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.Balance) + BalanceOrBuilder { + private static final long serialVersionUID = 0L; + // Use Balance.newBuilder() to construct. + private Balance(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Balance() { + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new Balance(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Balance( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: { + + valueZat_ = input.readInt64(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_Balance_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_Balance_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.Balance.class, cash.z.wallet.sdk.rpc.Service.Balance.Builder.class); + } + + public static final int VALUEZAT_FIELD_NUMBER = 1; + private long valueZat_; + /** + * int64 valueZat = 1; + * @return The valueZat. + */ + @java.lang.Override + public long getValueZat() { + return valueZat_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (valueZat_ != 0L) { + output.writeInt64(1, valueZat_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (valueZat_ != 0L) { + size += com.google.protobuf.CodedOutputStream + .computeInt64Size(1, valueZat_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.Service.Balance)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.Service.Balance other = (cash.z.wallet.sdk.rpc.Service.Balance) obj; + + if (getValueZat() + != other.getValueZat()) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + VALUEZAT_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashLong( + getValueZat()); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.Service.Balance parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.Balance parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.Balance parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.Balance parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.Balance parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.Balance parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.Balance parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.Balance parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.Balance parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.Balance parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.Balance parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.Balance parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.Service.Balance prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code cash.z.wallet.sdk.rpc.Balance} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.Balance) + cash.z.wallet.sdk.rpc.Service.BalanceOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_Balance_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_Balance_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.Balance.class, cash.z.wallet.sdk.rpc.Service.Balance.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.Service.Balance.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + valueZat_ = 0L; + + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_Balance_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.Balance getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.Service.Balance.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.Balance build() { + cash.z.wallet.sdk.rpc.Service.Balance result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.Balance buildPartial() { + cash.z.wallet.sdk.rpc.Service.Balance result = new cash.z.wallet.sdk.rpc.Service.Balance(this); + result.valueZat_ = valueZat_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.Service.Balance) { + return mergeFrom((cash.z.wallet.sdk.rpc.Service.Balance)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.Service.Balance other) { + if (other == cash.z.wallet.sdk.rpc.Service.Balance.getDefaultInstance()) return this; + if (other.getValueZat() != 0L) { + setValueZat(other.getValueZat()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.Service.Balance parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.Service.Balance) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private long valueZat_ ; + /** + * int64 valueZat = 1; + * @return The valueZat. + */ + @java.lang.Override + public long getValueZat() { + return valueZat_; + } + /** + * int64 valueZat = 1; + * @param value The valueZat to set. + * @return This builder for chaining. + */ + public Builder setValueZat(long value) { + + valueZat_ = value; + onChanged(); + return this; + } + /** + * int64 valueZat = 1; + * @return This builder for chaining. + */ + public Builder clearValueZat() { + + valueZat_ = 0L; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.Balance) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.Balance) + private static final cash.z.wallet.sdk.rpc.Service.Balance DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.Service.Balance(); + } + + public static cash.z.wallet.sdk.rpc.Service.Balance getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public Balance parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Balance(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.Balance getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface ExcludeOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.Exclude) + com.google.protobuf.MessageOrBuilder { + + /** + * repeated bytes txid = 1; + * @return A list containing the txid. + */ + java.util.List getTxidList(); + /** + * repeated bytes txid = 1; + * @return The count of txid. + */ + int getTxidCount(); + /** + * repeated bytes txid = 1; + * @param index The index of the element to return. + * @return The txid at the given index. + */ + com.google.protobuf.ByteString getTxid(int index); + } + /** + * Protobuf type {@code cash.z.wallet.sdk.rpc.Exclude} + */ + public static final class Exclude extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.Exclude) + ExcludeOrBuilder { + private static final long serialVersionUID = 0L; + // Use Exclude.newBuilder() to construct. + private Exclude(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private Exclude() { + txid_ = java.util.Collections.emptyList(); + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new Exclude(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Exclude( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + if (!((mutable_bitField0_ & 0x00000001) != 0)) { + txid_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000001; + } + txid_.add(input.readBytes()); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) != 0)) { + txid_ = java.util.Collections.unmodifiableList(txid_); // C + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_Exclude_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_Exclude_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.Exclude.class, cash.z.wallet.sdk.rpc.Service.Exclude.Builder.class); + } + + public static final int TXID_FIELD_NUMBER = 1; + private java.util.List txid_; + /** + * repeated bytes txid = 1; + * @return A list containing the txid. + */ + @java.lang.Override + public java.util.List + getTxidList() { + return txid_; + } + /** + * repeated bytes txid = 1; + * @return The count of txid. + */ + public int getTxidCount() { + return txid_.size(); + } + /** + * repeated bytes txid = 1; + * @param index The index of the element to return. + * @return The txid at the given index. + */ + public com.google.protobuf.ByteString getTxid(int index) { + return txid_.get(index); + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + for (int i = 0; i < txid_.size(); i++) { + output.writeBytes(1, txid_.get(i)); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + { + int dataSize = 0; + for (int i = 0; i < txid_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(txid_.get(i)); + } + size += dataSize; + size += 1 * getTxidList().size(); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.Service.Exclude)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.Service.Exclude other = (cash.z.wallet.sdk.rpc.Service.Exclude) obj; + + if (!getTxidList() + .equals(other.getTxidList())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (getTxidCount() > 0) { + hash = (37 * hash) + TXID_FIELD_NUMBER; + hash = (53 * hash) + getTxidList().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.Service.Exclude parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.Exclude parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.Exclude parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.Exclude parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.Exclude parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.Exclude parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.Exclude parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.Exclude parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.Exclude parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.Exclude parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.Exclude parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.Exclude parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.Service.Exclude prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code cash.z.wallet.sdk.rpc.Exclude} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.Exclude) + cash.z.wallet.sdk.rpc.Service.ExcludeOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_Exclude_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_Exclude_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.Exclude.class, cash.z.wallet.sdk.rpc.Service.Exclude.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.Service.Exclude.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + txid_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_Exclude_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.Exclude getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.Service.Exclude.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.Exclude build() { + cash.z.wallet.sdk.rpc.Service.Exclude result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.Exclude buildPartial() { + cash.z.wallet.sdk.rpc.Service.Exclude result = new cash.z.wallet.sdk.rpc.Service.Exclude(this); + int from_bitField0_ = bitField0_; + if (((bitField0_ & 0x00000001) != 0)) { + txid_ = java.util.Collections.unmodifiableList(txid_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.txid_ = txid_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.Service.Exclude) { + return mergeFrom((cash.z.wallet.sdk.rpc.Service.Exclude)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.Service.Exclude other) { + if (other == cash.z.wallet.sdk.rpc.Service.Exclude.getDefaultInstance()) return this; + if (!other.txid_.isEmpty()) { + if (txid_.isEmpty()) { + txid_ = other.txid_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureTxidIsMutable(); + txid_.addAll(other.txid_); + } + onChanged(); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.Service.Exclude parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.Service.Exclude) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private java.util.List txid_ = java.util.Collections.emptyList(); + private void ensureTxidIsMutable() { + if (!((bitField0_ & 0x00000001) != 0)) { + txid_ = new java.util.ArrayList(txid_); + bitField0_ |= 0x00000001; + } + } + /** + * repeated bytes txid = 1; + * @return A list containing the txid. + */ + public java.util.List + getTxidList() { + return ((bitField0_ & 0x00000001) != 0) ? + java.util.Collections.unmodifiableList(txid_) : txid_; + } + /** + * repeated bytes txid = 1; + * @return The count of txid. + */ + public int getTxidCount() { + return txid_.size(); + } + /** + * repeated bytes txid = 1; + * @param index The index of the element to return. + * @return The txid at the given index. + */ + public com.google.protobuf.ByteString getTxid(int index) { + return txid_.get(index); + } + /** + * repeated bytes txid = 1; + * @param index The index to set the value at. + * @param value The txid to set. + * @return This builder for chaining. + */ + public Builder setTxid( + int index, com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureTxidIsMutable(); + txid_.set(index, value); + onChanged(); + return this; + } + /** + * repeated bytes txid = 1; + * @param value The txid to add. + * @return This builder for chaining. + */ + public Builder addTxid(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureTxidIsMutable(); + txid_.add(value); + onChanged(); + return this; + } + /** + * repeated bytes txid = 1; + * @param values The txid to add. + * @return This builder for chaining. + */ + public Builder addAllTxid( + java.lang.Iterable values) { + ensureTxidIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, txid_); + onChanged(); + return this; + } + /** + * repeated bytes txid = 1; + * @return This builder for chaining. + */ + public Builder clearTxid() { + txid_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.Exclude) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.Exclude) + private static final cash.z.wallet.sdk.rpc.Service.Exclude DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.Service.Exclude(); + } + + public static cash.z.wallet.sdk.rpc.Service.Exclude getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public Exclude parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Exclude(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.Exclude getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface TreeStateOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.TreeState) + com.google.protobuf.MessageOrBuilder { + + /** + *
+     * "main" or "test"
+     * 
+ * + * string network = 1; + * @return The network. + */ + java.lang.String getNetwork(); + /** + *
+     * "main" or "test"
+     * 
+ * + * string network = 1; + * @return The bytes for network. + */ + com.google.protobuf.ByteString + getNetworkBytes(); + + /** + * uint64 height = 2; + * @return The height. + */ + long getHeight(); + + /** + *
+     * block id
+     * 
+ * + * string hash = 3; + * @return The hash. + */ + java.lang.String getHash(); + /** + *
+     * block id
+     * 
+ * + * string hash = 3; + * @return The bytes for hash. + */ + com.google.protobuf.ByteString + getHashBytes(); + + /** + *
+     * Unix epoch time when the block was mined
+     * 
+ * + * uint32 time = 4; + * @return The time. + */ + int getTime(); + + /** + *
+     * sapling commitment tree state
+     * 
+ * + * string tree = 5; + * @return The tree. + */ + java.lang.String getTree(); + /** + *
+     * sapling commitment tree state
+     * 
+ * + * string tree = 5; + * @return The bytes for tree. + */ + com.google.protobuf.ByteString + getTreeBytes(); + } + /** + *
+   * The TreeState is derived from the Zcash z_gettreestate rpc.
+   * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.TreeState} + */ + public static final class TreeState extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.TreeState) + TreeStateOrBuilder { + private static final long serialVersionUID = 0L; + // Use TreeState.newBuilder() to construct. + private TreeState(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private TreeState() { + network_ = ""; + hash_ = ""; + tree_ = ""; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new TreeState(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private TreeState( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + java.lang.String s = input.readStringRequireUtf8(); + + network_ = s; + break; + } + case 16: { + + height_ = input.readUInt64(); + break; + } + case 26: { + java.lang.String s = input.readStringRequireUtf8(); + + hash_ = s; + break; + } + case 32: { + + time_ = input.readUInt32(); + break; + } + case 42: { + java.lang.String s = input.readStringRequireUtf8(); + + tree_ = s; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_TreeState_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_TreeState_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.TreeState.class, cash.z.wallet.sdk.rpc.Service.TreeState.Builder.class); + } + + public static final int NETWORK_FIELD_NUMBER = 1; + private volatile java.lang.Object network_; + /** + *
+     * "main" or "test"
+     * 
+ * + * string network = 1; + * @return The network. + */ + @java.lang.Override + public java.lang.String getNetwork() { + java.lang.Object ref = network_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + network_ = s; + return s; + } + } + /** + *
+     * "main" or "test"
+     * 
+ * + * string network = 1; + * @return The bytes for network. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getNetworkBytes() { + java.lang.Object ref = network_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + network_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int HEIGHT_FIELD_NUMBER = 2; + private long height_; + /** + * uint64 height = 2; + * @return The height. + */ + @java.lang.Override + public long getHeight() { + return height_; + } + + public static final int HASH_FIELD_NUMBER = 3; + private volatile java.lang.Object hash_; + /** + *
+     * block id
+     * 
+ * + * string hash = 3; + * @return The hash. + */ + @java.lang.Override + public java.lang.String getHash() { + java.lang.Object ref = hash_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + hash_ = s; + return s; + } + } + /** + *
+     * block id
+     * 
+ * + * string hash = 3; + * @return The bytes for hash. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getHashBytes() { + java.lang.Object ref = hash_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + hash_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int TIME_FIELD_NUMBER = 4; + private int time_; + /** + *
+     * Unix epoch time when the block was mined
+     * 
+ * + * uint32 time = 4; + * @return The time. + */ + @java.lang.Override + public int getTime() { + return time_; + } + + public static final int TREE_FIELD_NUMBER = 5; + private volatile java.lang.Object tree_; + /** + *
+     * sapling commitment tree state
+     * 
+ * + * string tree = 5; + * @return The tree. + */ + @java.lang.Override + public java.lang.String getTree() { + java.lang.Object ref = tree_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + tree_ = s; + return s; + } + } + /** + *
+     * sapling commitment tree state
+     * 
+ * + * string tree = 5; + * @return The bytes for tree. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getTreeBytes() { + java.lang.Object ref = tree_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + tree_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(network_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, network_); + } + if (height_ != 0L) { + output.writeUInt64(2, height_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(hash_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 3, hash_); + } + if (time_ != 0) { + output.writeUInt32(4, time_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(tree_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 5, tree_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(network_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, network_); + } + if (height_ != 0L) { + size += com.google.protobuf.CodedOutputStream + .computeUInt64Size(2, height_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(hash_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, hash_); + } + if (time_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeUInt32Size(4, time_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(tree_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, tree_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.Service.TreeState)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.Service.TreeState other = (cash.z.wallet.sdk.rpc.Service.TreeState) obj; + + if (!getNetwork() + .equals(other.getNetwork())) return false; + if (getHeight() + != other.getHeight()) return false; + if (!getHash() + .equals(other.getHash())) return false; + if (getTime() + != other.getTime()) return false; + if (!getTree() + .equals(other.getTree())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + NETWORK_FIELD_NUMBER; + hash = (53 * hash) + getNetwork().hashCode(); + hash = (37 * hash) + HEIGHT_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashLong( + getHeight()); + hash = (37 * hash) + HASH_FIELD_NUMBER; + hash = (53 * hash) + getHash().hashCode(); + hash = (37 * hash) + TIME_FIELD_NUMBER; + hash = (53 * hash) + getTime(); + hash = (37 * hash) + TREE_FIELD_NUMBER; + hash = (53 * hash) + getTree().hashCode(); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.Service.TreeState parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.TreeState parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.TreeState parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.TreeState parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.TreeState parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.TreeState parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.TreeState parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.TreeState parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.TreeState parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.TreeState parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.TreeState parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.TreeState parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.Service.TreeState prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * The TreeState is derived from the Zcash z_gettreestate rpc.
+     * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.TreeState} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.TreeState) + cash.z.wallet.sdk.rpc.Service.TreeStateOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_TreeState_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_TreeState_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.TreeState.class, cash.z.wallet.sdk.rpc.Service.TreeState.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.Service.TreeState.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + network_ = ""; + + height_ = 0L; + + hash_ = ""; + + time_ = 0; + + tree_ = ""; + + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_TreeState_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.TreeState getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.Service.TreeState.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.TreeState build() { + cash.z.wallet.sdk.rpc.Service.TreeState result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.TreeState buildPartial() { + cash.z.wallet.sdk.rpc.Service.TreeState result = new cash.z.wallet.sdk.rpc.Service.TreeState(this); + result.network_ = network_; + result.height_ = height_; + result.hash_ = hash_; + result.time_ = time_; + result.tree_ = tree_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.Service.TreeState) { + return mergeFrom((cash.z.wallet.sdk.rpc.Service.TreeState)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.Service.TreeState other) { + if (other == cash.z.wallet.sdk.rpc.Service.TreeState.getDefaultInstance()) return this; + if (!other.getNetwork().isEmpty()) { + network_ = other.network_; + onChanged(); + } + if (other.getHeight() != 0L) { + setHeight(other.getHeight()); + } + if (!other.getHash().isEmpty()) { + hash_ = other.hash_; + onChanged(); + } + if (other.getTime() != 0) { + setTime(other.getTime()); + } + if (!other.getTree().isEmpty()) { + tree_ = other.tree_; + onChanged(); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.Service.TreeState parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.Service.TreeState) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private java.lang.Object network_ = ""; + /** + *
+       * "main" or "test"
+       * 
+ * + * string network = 1; + * @return The network. + */ + public java.lang.String getNetwork() { + java.lang.Object ref = network_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + network_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + *
+       * "main" or "test"
+       * 
+ * + * string network = 1; + * @return The bytes for network. + */ + public com.google.protobuf.ByteString + getNetworkBytes() { + java.lang.Object ref = network_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + network_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + *
+       * "main" or "test"
+       * 
+ * + * string network = 1; + * @param value The network to set. + * @return This builder for chaining. + */ + public Builder setNetwork( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + network_ = value; + onChanged(); + return this; + } + /** + *
+       * "main" or "test"
+       * 
+ * + * string network = 1; + * @return This builder for chaining. + */ + public Builder clearNetwork() { + + network_ = getDefaultInstance().getNetwork(); + onChanged(); + return this; + } + /** + *
+       * "main" or "test"
+       * 
+ * + * string network = 1; + * @param value The bytes for network to set. + * @return This builder for chaining. + */ + public Builder setNetworkBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + network_ = value; + onChanged(); + return this; + } + + private long height_ ; + /** + * uint64 height = 2; + * @return The height. + */ + @java.lang.Override + public long getHeight() { + return height_; + } + /** + * uint64 height = 2; + * @param value The height to set. + * @return This builder for chaining. + */ + public Builder setHeight(long value) { + + height_ = value; + onChanged(); + return this; + } + /** + * uint64 height = 2; + * @return This builder for chaining. + */ + public Builder clearHeight() { + + height_ = 0L; + onChanged(); + return this; + } + + private java.lang.Object hash_ = ""; + /** + *
+       * block id
+       * 
+ * + * string hash = 3; + * @return The hash. + */ + public java.lang.String getHash() { + java.lang.Object ref = hash_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + hash_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + *
+       * block id
+       * 
+ * + * string hash = 3; + * @return The bytes for hash. + */ + public com.google.protobuf.ByteString + getHashBytes() { + java.lang.Object ref = hash_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + hash_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + *
+       * block id
+       * 
+ * + * string hash = 3; + * @param value The hash to set. + * @return This builder for chaining. + */ + public Builder setHash( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + hash_ = value; + onChanged(); + return this; + } + /** + *
+       * block id
+       * 
+ * + * string hash = 3; + * @return This builder for chaining. + */ + public Builder clearHash() { + + hash_ = getDefaultInstance().getHash(); + onChanged(); + return this; + } + /** + *
+       * block id
+       * 
+ * + * string hash = 3; + * @param value The bytes for hash to set. + * @return This builder for chaining. + */ + public Builder setHashBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + hash_ = value; + onChanged(); + return this; + } + + private int time_ ; + /** + *
+       * Unix epoch time when the block was mined
+       * 
+ * + * uint32 time = 4; + * @return The time. + */ + @java.lang.Override + public int getTime() { + return time_; + } + /** + *
+       * Unix epoch time when the block was mined
+       * 
+ * + * uint32 time = 4; + * @param value The time to set. + * @return This builder for chaining. + */ + public Builder setTime(int value) { + + time_ = value; + onChanged(); + return this; + } + /** + *
+       * Unix epoch time when the block was mined
+       * 
+ * + * uint32 time = 4; + * @return This builder for chaining. + */ + public Builder clearTime() { + + time_ = 0; + onChanged(); + return this; + } + + private java.lang.Object tree_ = ""; + /** + *
+       * sapling commitment tree state
+       * 
+ * + * string tree = 5; + * @return The tree. + */ + public java.lang.String getTree() { + java.lang.Object ref = tree_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + tree_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + *
+       * sapling commitment tree state
+       * 
+ * + * string tree = 5; + * @return The bytes for tree. + */ + public com.google.protobuf.ByteString + getTreeBytes() { + java.lang.Object ref = tree_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + tree_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + *
+       * sapling commitment tree state
+       * 
+ * + * string tree = 5; + * @param value The tree to set. + * @return This builder for chaining. + */ + public Builder setTree( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + tree_ = value; + onChanged(); + return this; + } + /** + *
+       * sapling commitment tree state
+       * 
+ * + * string tree = 5; + * @return This builder for chaining. + */ + public Builder clearTree() { + + tree_ = getDefaultInstance().getTree(); + onChanged(); + return this; + } + /** + *
+       * sapling commitment tree state
+       * 
+ * + * string tree = 5; + * @param value The bytes for tree to set. + * @return This builder for chaining. + */ + public Builder setTreeBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + tree_ = value; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.TreeState) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.TreeState) + private static final cash.z.wallet.sdk.rpc.Service.TreeState DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.Service.TreeState(); + } + + public static cash.z.wallet.sdk.rpc.Service.TreeState getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public TreeState parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new TreeState(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.TreeState getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface GetAddressUtxosArgOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.GetAddressUtxosArg) + com.google.protobuf.MessageOrBuilder { + + /** + * repeated string addresses = 1; + * @return A list containing the addresses. + */ + java.util.List + getAddressesList(); + /** + * repeated string addresses = 1; + * @return The count of addresses. + */ + int getAddressesCount(); + /** + * repeated string addresses = 1; + * @param index The index of the element to return. + * @return The addresses at the given index. + */ + java.lang.String getAddresses(int index); + /** + * repeated string addresses = 1; + * @param index The index of the value to return. + * @return The bytes of the addresses at the given index. + */ + com.google.protobuf.ByteString + getAddressesBytes(int index); + + /** + * uint64 startHeight = 2; + * @return The startHeight. + */ + long getStartHeight(); + + /** + *
+     * zero means unlimited
+     * 
+ * + * uint32 maxEntries = 3; + * @return The maxEntries. + */ + int getMaxEntries(); + } + /** + *
+   * Results are sorted by height, which makes it easy to issue another
+   * request that picks up from where the previous left off.
+   * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.GetAddressUtxosArg} + */ + public static final class GetAddressUtxosArg extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.GetAddressUtxosArg) + GetAddressUtxosArgOrBuilder { + private static final long serialVersionUID = 0L; + // Use GetAddressUtxosArg.newBuilder() to construct. + private GetAddressUtxosArg(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private GetAddressUtxosArg() { + addresses_ = com.google.protobuf.LazyStringArrayList.EMPTY; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new GetAddressUtxosArg(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private GetAddressUtxosArg( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + java.lang.String s = input.readStringRequireUtf8(); + if (!((mutable_bitField0_ & 0x00000001) != 0)) { + addresses_ = new com.google.protobuf.LazyStringArrayList(); + mutable_bitField0_ |= 0x00000001; + } + addresses_.add(s); + break; + } + case 16: { + + startHeight_ = input.readUInt64(); + break; + } + case 24: { + + maxEntries_ = input.readUInt32(); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) != 0)) { + addresses_ = addresses_.getUnmodifiableView(); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosArg_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosArg_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg.class, cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg.Builder.class); + } + + public static final int ADDRESSES_FIELD_NUMBER = 1; + private com.google.protobuf.LazyStringList addresses_; + /** + * repeated string addresses = 1; + * @return A list containing the addresses. + */ + public com.google.protobuf.ProtocolStringList + getAddressesList() { + return addresses_; + } + /** + * repeated string addresses = 1; + * @return The count of addresses. + */ + public int getAddressesCount() { + return addresses_.size(); + } + /** + * repeated string addresses = 1; + * @param index The index of the element to return. + * @return The addresses at the given index. + */ + public java.lang.String getAddresses(int index) { + return addresses_.get(index); + } + /** + * repeated string addresses = 1; + * @param index The index of the value to return. + * @return The bytes of the addresses at the given index. + */ + public com.google.protobuf.ByteString + getAddressesBytes(int index) { + return addresses_.getByteString(index); + } + + public static final int STARTHEIGHT_FIELD_NUMBER = 2; + private long startHeight_; + /** + * uint64 startHeight = 2; + * @return The startHeight. + */ + @java.lang.Override + public long getStartHeight() { + return startHeight_; + } + + public static final int MAXENTRIES_FIELD_NUMBER = 3; + private int maxEntries_; + /** + *
+     * zero means unlimited
+     * 
+ * + * uint32 maxEntries = 3; + * @return The maxEntries. + */ + @java.lang.Override + public int getMaxEntries() { + return maxEntries_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + for (int i = 0; i < addresses_.size(); i++) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 1, addresses_.getRaw(i)); + } + if (startHeight_ != 0L) { + output.writeUInt64(2, startHeight_); + } + if (maxEntries_ != 0) { + output.writeUInt32(3, maxEntries_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + { + int dataSize = 0; + for (int i = 0; i < addresses_.size(); i++) { + dataSize += computeStringSizeNoTag(addresses_.getRaw(i)); + } + size += dataSize; + size += 1 * getAddressesList().size(); + } + if (startHeight_ != 0L) { + size += com.google.protobuf.CodedOutputStream + .computeUInt64Size(2, startHeight_); + } + if (maxEntries_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeUInt32Size(3, maxEntries_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg other = (cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg) obj; + + if (!getAddressesList() + .equals(other.getAddressesList())) return false; + if (getStartHeight() + != other.getStartHeight()) return false; + if (getMaxEntries() + != other.getMaxEntries()) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (getAddressesCount() > 0) { + hash = (37 * hash) + ADDRESSES_FIELD_NUMBER; + hash = (53 * hash) + getAddressesList().hashCode(); + } + hash = (37 * hash) + STARTHEIGHT_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashLong( + getStartHeight()); + hash = (37 * hash) + MAXENTRIES_FIELD_NUMBER; + hash = (53 * hash) + getMaxEntries(); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * Results are sorted by height, which makes it easy to issue another
+     * request that picks up from where the previous left off.
+     * 
+ * + * Protobuf type {@code cash.z.wallet.sdk.rpc.GetAddressUtxosArg} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.GetAddressUtxosArg) + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArgOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosArg_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosArg_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg.class, cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + addresses_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + startHeight_ = 0L; + + maxEntries_ = 0; + + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosArg_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg build() { + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg buildPartial() { + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg result = new cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg(this); + int from_bitField0_ = bitField0_; + if (((bitField0_ & 0x00000001) != 0)) { + addresses_ = addresses_.getUnmodifiableView(); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.addresses_ = addresses_; + result.startHeight_ = startHeight_; + result.maxEntries_ = maxEntries_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg) { + return mergeFrom((cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg other) { + if (other == cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg.getDefaultInstance()) return this; + if (!other.addresses_.isEmpty()) { + if (addresses_.isEmpty()) { + addresses_ = other.addresses_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureAddressesIsMutable(); + addresses_.addAll(other.addresses_); + } + onChanged(); + } + if (other.getStartHeight() != 0L) { + setStartHeight(other.getStartHeight()); + } + if (other.getMaxEntries() != 0) { + setMaxEntries(other.getMaxEntries()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private com.google.protobuf.LazyStringList addresses_ = com.google.protobuf.LazyStringArrayList.EMPTY; + private void ensureAddressesIsMutable() { + if (!((bitField0_ & 0x00000001) != 0)) { + addresses_ = new com.google.protobuf.LazyStringArrayList(addresses_); + bitField0_ |= 0x00000001; + } + } + /** + * repeated string addresses = 1; + * @return A list containing the addresses. + */ + public com.google.protobuf.ProtocolStringList + getAddressesList() { + return addresses_.getUnmodifiableView(); + } + /** + * repeated string addresses = 1; + * @return The count of addresses. + */ + public int getAddressesCount() { + return addresses_.size(); + } + /** + * repeated string addresses = 1; + * @param index The index of the element to return. + * @return The addresses at the given index. + */ + public java.lang.String getAddresses(int index) { + return addresses_.get(index); + } + /** + * repeated string addresses = 1; + * @param index The index of the value to return. + * @return The bytes of the addresses at the given index. + */ + public com.google.protobuf.ByteString + getAddressesBytes(int index) { + return addresses_.getByteString(index); + } + /** + * repeated string addresses = 1; + * @param index The index to set the value at. + * @param value The addresses to set. + * @return This builder for chaining. + */ + public Builder setAddresses( + int index, java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureAddressesIsMutable(); + addresses_.set(index, value); + onChanged(); + return this; + } + /** + * repeated string addresses = 1; + * @param value The addresses to add. + * @return This builder for chaining. + */ + public Builder addAddresses( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureAddressesIsMutable(); + addresses_.add(value); + onChanged(); + return this; + } + /** + * repeated string addresses = 1; + * @param values The addresses to add. + * @return This builder for chaining. + */ + public Builder addAllAddresses( + java.lang.Iterable values) { + ensureAddressesIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, addresses_); + onChanged(); + return this; + } + /** + * repeated string addresses = 1; + * @return This builder for chaining. + */ + public Builder clearAddresses() { + addresses_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + return this; + } + /** + * repeated string addresses = 1; + * @param value The bytes of the addresses to add. + * @return This builder for chaining. + */ + public Builder addAddressesBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + ensureAddressesIsMutable(); + addresses_.add(value); + onChanged(); + return this; + } + + private long startHeight_ ; + /** + * uint64 startHeight = 2; + * @return The startHeight. + */ + @java.lang.Override + public long getStartHeight() { + return startHeight_; + } + /** + * uint64 startHeight = 2; + * @param value The startHeight to set. + * @return This builder for chaining. + */ + public Builder setStartHeight(long value) { + + startHeight_ = value; + onChanged(); + return this; + } + /** + * uint64 startHeight = 2; + * @return This builder for chaining. + */ + public Builder clearStartHeight() { + + startHeight_ = 0L; + onChanged(); + return this; + } + + private int maxEntries_ ; + /** + *
+       * zero means unlimited
+       * 
+ * + * uint32 maxEntries = 3; + * @return The maxEntries. + */ + @java.lang.Override + public int getMaxEntries() { + return maxEntries_; + } + /** + *
+       * zero means unlimited
+       * 
+ * + * uint32 maxEntries = 3; + * @param value The maxEntries to set. + * @return This builder for chaining. + */ + public Builder setMaxEntries(int value) { + + maxEntries_ = value; + onChanged(); + return this; + } + /** + *
+       * zero means unlimited
+       * 
+ * + * uint32 maxEntries = 3; + * @return This builder for chaining. + */ + public Builder clearMaxEntries() { + + maxEntries_ = 0; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.GetAddressUtxosArg) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.GetAddressUtxosArg) + private static final cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg(); + } + + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public GetAddressUtxosArg parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new GetAddressUtxosArg(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.GetAddressUtxosArg getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface GetAddressUtxosReplyOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.GetAddressUtxosReply) + com.google.protobuf.MessageOrBuilder { + + /** + * string address = 6; + * @return The address. + */ + java.lang.String getAddress(); + /** + * string address = 6; + * @return The bytes for address. + */ + com.google.protobuf.ByteString + getAddressBytes(); + + /** + * bytes txid = 1; + * @return The txid. + */ + com.google.protobuf.ByteString getTxid(); + + /** + * int32 index = 2; + * @return The index. + */ + int getIndex(); + + /** + * bytes script = 3; + * @return The script. + */ + com.google.protobuf.ByteString getScript(); + + /** + * int64 valueZat = 4; + * @return The valueZat. + */ + long getValueZat(); + + /** + * uint64 height = 5; + * @return The height. + */ + long getHeight(); + } + /** + * Protobuf type {@code cash.z.wallet.sdk.rpc.GetAddressUtxosReply} + */ + public static final class GetAddressUtxosReply extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.GetAddressUtxosReply) + GetAddressUtxosReplyOrBuilder { + private static final long serialVersionUID = 0L; + // Use GetAddressUtxosReply.newBuilder() to construct. + private GetAddressUtxosReply(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private GetAddressUtxosReply() { + address_ = ""; + txid_ = com.google.protobuf.ByteString.EMPTY; + script_ = com.google.protobuf.ByteString.EMPTY; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new GetAddressUtxosReply(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private GetAddressUtxosReply( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + + txid_ = input.readBytes(); + break; + } + case 16: { + + index_ = input.readInt32(); + break; + } + case 26: { + + script_ = input.readBytes(); + break; + } + case 32: { + + valueZat_ = input.readInt64(); + break; + } + case 40: { + + height_ = input.readUInt64(); + break; + } + case 50: { + java.lang.String s = input.readStringRequireUtf8(); + + address_ = s; + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosReply_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosReply_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply.class, cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply.Builder.class); + } + + public static final int ADDRESS_FIELD_NUMBER = 6; + private volatile java.lang.Object address_; + /** + * string address = 6; + * @return The address. + */ + @java.lang.Override + public java.lang.String getAddress() { + java.lang.Object ref = address_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + address_ = s; + return s; + } + } + /** + * string address = 6; + * @return The bytes for address. + */ + @java.lang.Override + public com.google.protobuf.ByteString + getAddressBytes() { + java.lang.Object ref = address_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + address_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + public static final int TXID_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString txid_; + /** + * bytes txid = 1; + * @return The txid. + */ + @java.lang.Override + public com.google.protobuf.ByteString getTxid() { + return txid_; + } + + public static final int INDEX_FIELD_NUMBER = 2; + private int index_; + /** + * int32 index = 2; + * @return The index. + */ + @java.lang.Override + public int getIndex() { + return index_; + } + + public static final int SCRIPT_FIELD_NUMBER = 3; + private com.google.protobuf.ByteString script_; + /** + * bytes script = 3; + * @return The script. + */ + @java.lang.Override + public com.google.protobuf.ByteString getScript() { + return script_; + } + + public static final int VALUEZAT_FIELD_NUMBER = 4; + private long valueZat_; + /** + * int64 valueZat = 4; + * @return The valueZat. + */ + @java.lang.Override + public long getValueZat() { + return valueZat_; + } + + public static final int HEIGHT_FIELD_NUMBER = 5; + private long height_; + /** + * uint64 height = 5; + * @return The height. + */ + @java.lang.Override + public long getHeight() { + return height_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!txid_.isEmpty()) { + output.writeBytes(1, txid_); + } + if (index_ != 0) { + output.writeInt32(2, index_); + } + if (!script_.isEmpty()) { + output.writeBytes(3, script_); + } + if (valueZat_ != 0L) { + output.writeInt64(4, valueZat_); + } + if (height_ != 0L) { + output.writeUInt64(5, height_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(address_)) { + com.google.protobuf.GeneratedMessageV3.writeString(output, 6, address_); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!txid_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, txid_); + } + if (index_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(2, index_); + } + if (!script_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, script_); + } + if (valueZat_ != 0L) { + size += com.google.protobuf.CodedOutputStream + .computeInt64Size(4, valueZat_); + } + if (height_ != 0L) { + size += com.google.protobuf.CodedOutputStream + .computeUInt64Size(5, height_); + } + if (!com.google.protobuf.GeneratedMessageV3.isStringEmpty(address_)) { + size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, address_); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply other = (cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply) obj; + + if (!getAddress() + .equals(other.getAddress())) return false; + if (!getTxid() + .equals(other.getTxid())) return false; + if (getIndex() + != other.getIndex()) return false; + if (!getScript() + .equals(other.getScript())) return false; + if (getValueZat() + != other.getValueZat()) return false; + if (getHeight() + != other.getHeight()) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + ADDRESS_FIELD_NUMBER; + hash = (53 * hash) + getAddress().hashCode(); + hash = (37 * hash) + TXID_FIELD_NUMBER; + hash = (53 * hash) + getTxid().hashCode(); + hash = (37 * hash) + INDEX_FIELD_NUMBER; + hash = (53 * hash) + getIndex(); + hash = (37 * hash) + SCRIPT_FIELD_NUMBER; + hash = (53 * hash) + getScript().hashCode(); + hash = (37 * hash) + VALUEZAT_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashLong( + getValueZat()); + hash = (37 * hash) + HEIGHT_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashLong( + getHeight()); + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code cash.z.wallet.sdk.rpc.GetAddressUtxosReply} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.GetAddressUtxosReply) + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosReply_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosReply_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply.class, cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + address_ = ""; + + txid_ = com.google.protobuf.ByteString.EMPTY; + + index_ = 0; + + script_ = com.google.protobuf.ByteString.EMPTY; + + valueZat_ = 0L; + + height_ = 0L; + + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosReply_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply build() { + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply buildPartial() { + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply result = new cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply(this); + result.address_ = address_; + result.txid_ = txid_; + result.index_ = index_; + result.script_ = script_; + result.valueZat_ = valueZat_; + result.height_ = height_; + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply) { + return mergeFrom((cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply other) { + if (other == cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply.getDefaultInstance()) return this; + if (!other.getAddress().isEmpty()) { + address_ = other.address_; + onChanged(); + } + if (other.getTxid() != com.google.protobuf.ByteString.EMPTY) { + setTxid(other.getTxid()); + } + if (other.getIndex() != 0) { + setIndex(other.getIndex()); + } + if (other.getScript() != com.google.protobuf.ByteString.EMPTY) { + setScript(other.getScript()); + } + if (other.getValueZat() != 0L) { + setValueZat(other.getValueZat()); + } + if (other.getHeight() != 0L) { + setHeight(other.getHeight()); + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + + private java.lang.Object address_ = ""; + /** + * string address = 6; + * @return The address. + */ + public java.lang.String getAddress() { + java.lang.Object ref = address_; + if (!(ref instanceof java.lang.String)) { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + address_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * string address = 6; + * @return The bytes for address. + */ + public com.google.protobuf.ByteString + getAddressBytes() { + java.lang.Object ref = address_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + address_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * string address = 6; + * @param value The address to set. + * @return This builder for chaining. + */ + public Builder setAddress( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + + address_ = value; + onChanged(); + return this; + } + /** + * string address = 6; + * @return This builder for chaining. + */ + public Builder clearAddress() { + + address_ = getDefaultInstance().getAddress(); + onChanged(); + return this; + } + /** + * string address = 6; + * @param value The bytes for address to set. + * @return This builder for chaining. + */ + public Builder setAddressBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + checkByteStringIsUtf8(value); + + address_ = value; + onChanged(); + return this; + } + + private com.google.protobuf.ByteString txid_ = com.google.protobuf.ByteString.EMPTY; + /** + * bytes txid = 1; + * @return The txid. + */ + @java.lang.Override + public com.google.protobuf.ByteString getTxid() { + return txid_; + } + /** + * bytes txid = 1; + * @param value The txid to set. + * @return This builder for chaining. + */ + public Builder setTxid(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + + txid_ = value; + onChanged(); + return this; + } + /** + * bytes txid = 1; + * @return This builder for chaining. + */ + public Builder clearTxid() { + + txid_ = getDefaultInstance().getTxid(); + onChanged(); + return this; + } + + private int index_ ; + /** + * int32 index = 2; + * @return The index. + */ + @java.lang.Override + public int getIndex() { + return index_; + } + /** + * int32 index = 2; + * @param value The index to set. + * @return This builder for chaining. + */ + public Builder setIndex(int value) { + + index_ = value; + onChanged(); + return this; + } + /** + * int32 index = 2; + * @return This builder for chaining. + */ + public Builder clearIndex() { + + index_ = 0; + onChanged(); + return this; + } + + private com.google.protobuf.ByteString script_ = com.google.protobuf.ByteString.EMPTY; + /** + * bytes script = 3; + * @return The script. + */ + @java.lang.Override + public com.google.protobuf.ByteString getScript() { + return script_; + } + /** + * bytes script = 3; + * @param value The script to set. + * @return This builder for chaining. + */ + public Builder setScript(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + + script_ = value; + onChanged(); + return this; + } + /** + * bytes script = 3; + * @return This builder for chaining. + */ + public Builder clearScript() { + + script_ = getDefaultInstance().getScript(); + onChanged(); + return this; + } + + private long valueZat_ ; + /** + * int64 valueZat = 4; + * @return The valueZat. + */ + @java.lang.Override + public long getValueZat() { + return valueZat_; + } + /** + * int64 valueZat = 4; + * @param value The valueZat to set. + * @return This builder for chaining. + */ + public Builder setValueZat(long value) { + + valueZat_ = value; + onChanged(); + return this; + } + /** + * int64 valueZat = 4; + * @return This builder for chaining. + */ + public Builder clearValueZat() { + + valueZat_ = 0L; + onChanged(); + return this; + } + + private long height_ ; + /** + * uint64 height = 5; + * @return The height. + */ + @java.lang.Override + public long getHeight() { + return height_; + } + /** + * uint64 height = 5; + * @param value The height to set. + * @return This builder for chaining. + */ + public Builder setHeight(long value) { + + height_ = value; + onChanged(); + return this; + } + /** + * uint64 height = 5; + * @return This builder for chaining. + */ + public Builder clearHeight() { + + height_ = 0L; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.GetAddressUtxosReply) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.GetAddressUtxosReply) + private static final cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply(); + } + + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public GetAddressUtxosReply parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new GetAddressUtxosReply(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface GetAddressUtxosReplyListOrBuilder extends + // @@protoc_insertion_point(interface_extends:cash.z.wallet.sdk.rpc.GetAddressUtxosReplyList) + com.google.protobuf.MessageOrBuilder { + + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + java.util.List + getAddressUtxosList(); + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply getAddressUtxos(int index); + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + int getAddressUtxosCount(); + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + java.util.List + getAddressUtxosOrBuilderList(); + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyOrBuilder getAddressUtxosOrBuilder( + int index); + } + /** + * Protobuf type {@code cash.z.wallet.sdk.rpc.GetAddressUtxosReplyList} + */ + public static final class GetAddressUtxosReplyList extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:cash.z.wallet.sdk.rpc.GetAddressUtxosReplyList) + GetAddressUtxosReplyListOrBuilder { + private static final long serialVersionUID = 0L; + // Use GetAddressUtxosReplyList.newBuilder() to construct. + private GetAddressUtxosReplyList(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private GetAddressUtxosReplyList() { + addressUtxos_ = java.util.Collections.emptyList(); + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new GetAddressUtxosReplyList(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private GetAddressUtxosReplyList( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + this(); + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + if (!((mutable_bitField0_ & 0x00000001) != 0)) { + addressUtxos_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000001; + } + addressUtxos_.add( + input.readMessage(cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply.parser(), extensionRegistry)); + break; + } + default: { + if (!parseUnknownField( + input, unknownFields, extensionRegistry, tag)) { + done = true; + } + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) != 0)) { + addressUtxos_ = java.util.Collections.unmodifiableList(addressUtxos_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosReplyList_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosReplyList_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList.class, cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList.Builder.class); + } + + public static final int ADDRESSUTXOS_FIELD_NUMBER = 1; + private java.util.List addressUtxos_; + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + @java.lang.Override + public java.util.List getAddressUtxosList() { + return addressUtxos_; + } + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + @java.lang.Override + public java.util.List + getAddressUtxosOrBuilderList() { + return addressUtxos_; + } + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + @java.lang.Override + public int getAddressUtxosCount() { + return addressUtxos_.size(); + } + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply getAddressUtxos(int index) { + return addressUtxos_.get(index); + } + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyOrBuilder getAddressUtxosOrBuilder( + int index) { + return addressUtxos_.get(index); + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + for (int i = 0; i < addressUtxos_.size(); i++) { + output.writeMessage(1, addressUtxos_.get(i)); + } + unknownFields.writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + for (int i = 0; i < addressUtxos_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, addressUtxos_.get(i)); + } + size += unknownFields.getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList)) { + return super.equals(obj); + } + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList other = (cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList) obj; + + if (!getAddressUtxosList() + .equals(other.getAddressUtxosList())) return false; + if (!unknownFields.equals(other.unknownFields)) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (getAddressUtxosCount() > 0) { + hash = (37 * hash) + ADDRESSUTXOS_FIELD_NUMBER; + hash = (53 * hash) + getAddressUtxosList().hashCode(); + } + hash = (29 * hash) + unknownFields.hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code cash.z.wallet.sdk.rpc.GetAddressUtxosReplyList} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:cash.z.wallet.sdk.rpc.GetAddressUtxosReplyList) + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyListOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosReplyList_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosReplyList_fieldAccessorTable + .ensureFieldAccessorsInitialized( + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList.class, cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList.Builder.class); + } + + // Construct using cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessageV3 + .alwaysUseFieldBuilders) { + getAddressUtxosFieldBuilder(); + } + } + @java.lang.Override + public Builder clear() { + super.clear(); + if (addressUtxosBuilder_ == null) { + addressUtxos_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + } else { + addressUtxosBuilder_.clear(); + } + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return cash.z.wallet.sdk.rpc.Service.internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosReplyList_descriptor; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList getDefaultInstanceForType() { + return cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList.getDefaultInstance(); + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList build() { + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList buildPartial() { + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList result = new cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList(this); + int from_bitField0_ = bitField0_; + if (addressUtxosBuilder_ == null) { + if (((bitField0_ & 0x00000001) != 0)) { + addressUtxos_ = java.util.Collections.unmodifiableList(addressUtxos_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.addressUtxos_ = addressUtxos_; + } else { + result.addressUtxos_ = addressUtxosBuilder_.build(); + } + onBuilt(); + return result; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList) { + return mergeFrom((cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList other) { + if (other == cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList.getDefaultInstance()) return this; + if (addressUtxosBuilder_ == null) { + if (!other.addressUtxos_.isEmpty()) { + if (addressUtxos_.isEmpty()) { + addressUtxos_ = other.addressUtxos_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureAddressUtxosIsMutable(); + addressUtxos_.addAll(other.addressUtxos_); + } + onChanged(); + } + } else { + if (!other.addressUtxos_.isEmpty()) { + if (addressUtxosBuilder_.isEmpty()) { + addressUtxosBuilder_.dispose(); + addressUtxosBuilder_ = null; + addressUtxos_ = other.addressUtxos_; + bitField0_ = (bitField0_ & ~0x00000001); + addressUtxosBuilder_ = + com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ? + getAddressUtxosFieldBuilder() : null; + } else { + addressUtxosBuilder_.addAllMessages(other.addressUtxos_); + } + } + } + this.mergeUnknownFields(other.unknownFields); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList) e.getUnfinishedMessage(); + throw e.unwrapIOException(); + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private java.util.List addressUtxos_ = + java.util.Collections.emptyList(); + private void ensureAddressUtxosIsMutable() { + if (!((bitField0_ & 0x00000001) != 0)) { + addressUtxos_ = new java.util.ArrayList(addressUtxos_); + bitField0_ |= 0x00000001; + } + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply, cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply.Builder, cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyOrBuilder> addressUtxosBuilder_; + + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + public java.util.List getAddressUtxosList() { + if (addressUtxosBuilder_ == null) { + return java.util.Collections.unmodifiableList(addressUtxos_); + } else { + return addressUtxosBuilder_.getMessageList(); + } + } + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + public int getAddressUtxosCount() { + if (addressUtxosBuilder_ == null) { + return addressUtxos_.size(); + } else { + return addressUtxosBuilder_.getCount(); + } + } + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + public cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply getAddressUtxos(int index) { + if (addressUtxosBuilder_ == null) { + return addressUtxos_.get(index); + } else { + return addressUtxosBuilder_.getMessage(index); + } + } + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + public Builder setAddressUtxos( + int index, cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply value) { + if (addressUtxosBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureAddressUtxosIsMutable(); + addressUtxos_.set(index, value); + onChanged(); + } else { + addressUtxosBuilder_.setMessage(index, value); + } + return this; + } + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + public Builder setAddressUtxos( + int index, cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply.Builder builderForValue) { + if (addressUtxosBuilder_ == null) { + ensureAddressUtxosIsMutable(); + addressUtxos_.set(index, builderForValue.build()); + onChanged(); + } else { + addressUtxosBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + public Builder addAddressUtxos(cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply value) { + if (addressUtxosBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureAddressUtxosIsMutable(); + addressUtxos_.add(value); + onChanged(); + } else { + addressUtxosBuilder_.addMessage(value); + } + return this; + } + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + public Builder addAddressUtxos( + int index, cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply value) { + if (addressUtxosBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureAddressUtxosIsMutable(); + addressUtxos_.add(index, value); + onChanged(); + } else { + addressUtxosBuilder_.addMessage(index, value); + } + return this; + } + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + public Builder addAddressUtxos( + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply.Builder builderForValue) { + if (addressUtxosBuilder_ == null) { + ensureAddressUtxosIsMutable(); + addressUtxos_.add(builderForValue.build()); + onChanged(); + } else { + addressUtxosBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + public Builder addAddressUtxos( + int index, cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply.Builder builderForValue) { + if (addressUtxosBuilder_ == null) { + ensureAddressUtxosIsMutable(); + addressUtxos_.add(index, builderForValue.build()); + onChanged(); + } else { + addressUtxosBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + public Builder addAllAddressUtxos( + java.lang.Iterable values) { + if (addressUtxosBuilder_ == null) { + ensureAddressUtxosIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, addressUtxos_); + onChanged(); + } else { + addressUtxosBuilder_.addAllMessages(values); + } + return this; + } + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + public Builder clearAddressUtxos() { + if (addressUtxosBuilder_ == null) { + addressUtxos_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + } else { + addressUtxosBuilder_.clear(); + } + return this; + } + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + public Builder removeAddressUtxos(int index) { + if (addressUtxosBuilder_ == null) { + ensureAddressUtxosIsMutable(); + addressUtxos_.remove(index); + onChanged(); + } else { + addressUtxosBuilder_.remove(index); + } + return this; + } + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + public cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply.Builder getAddressUtxosBuilder( + int index) { + return getAddressUtxosFieldBuilder().getBuilder(index); + } + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + public cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyOrBuilder getAddressUtxosOrBuilder( + int index) { + if (addressUtxosBuilder_ == null) { + return addressUtxos_.get(index); } else { + return addressUtxosBuilder_.getMessageOrBuilder(index); + } + } + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + public java.util.List + getAddressUtxosOrBuilderList() { + if (addressUtxosBuilder_ != null) { + return addressUtxosBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(addressUtxos_); + } + } + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + public cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply.Builder addAddressUtxosBuilder() { + return getAddressUtxosFieldBuilder().addBuilder( + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply.getDefaultInstance()); + } + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + public cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply.Builder addAddressUtxosBuilder( + int index) { + return getAddressUtxosFieldBuilder().addBuilder( + index, cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply.getDefaultInstance()); + } + /** + * repeated .cash.z.wallet.sdk.rpc.GetAddressUtxosReply addressUtxos = 1; + */ + public java.util.List + getAddressUtxosBuilderList() { + return getAddressUtxosFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilderV3< + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply, cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply.Builder, cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyOrBuilder> + getAddressUtxosFieldBuilder() { + if (addressUtxosBuilder_ == null) { + addressUtxosBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3< + cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply, cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReply.Builder, cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyOrBuilder>( + addressUtxos_, + ((bitField0_ & 0x00000001) != 0), + getParentForChildren(), + isClean()); + addressUtxos_ = null; + } + return addressUtxosBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:cash.z.wallet.sdk.rpc.GetAddressUtxosReplyList) + } + + // @@protoc_insertion_point(class_scope:cash.z.wallet.sdk.rpc.GetAddressUtxosReplyList) + private static final cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList(); + } + + public static cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public GetAddressUtxosReplyList parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new GetAddressUtxosReplyList(input, extensionRegistry); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public cash.z.wallet.sdk.rpc.Service.GetAddressUtxosReplyList getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_BlockID_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_BlockID_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_BlockRange_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_BlockRange_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_TxFilter_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_TxFilter_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_RawTransaction_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_RawTransaction_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_SendResponse_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_SendResponse_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_ChainSpec_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_ChainSpec_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_Empty_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_Empty_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_LightdInfo_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_LightdInfo_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_TransparentAddressBlockFilter_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_TransparentAddressBlockFilter_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_Duration_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_Duration_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_PingResponse_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_PingResponse_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_Address_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_Address_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_AddressList_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_AddressList_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_Balance_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_Balance_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_Exclude_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_Exclude_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_TreeState_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_TreeState_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosArg_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosArg_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosReply_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosReply_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosReplyList_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosReplyList_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + java.lang.String[] descriptorData = { + "\n\rservice.proto\022\025cash.z.wallet.sdk.rpc\032\025" + + "compact_formats.proto\"\'\n\007BlockID\022\016\n\006heig" + + "ht\030\001 \001(\004\022\014\n\004hash\030\002 \001(\014\"h\n\nBlockRange\022-\n\005" + + "start\030\001 \001(\0132\036.cash.z.wallet.sdk.rpc.Bloc" + + "kID\022+\n\003end\030\002 \001(\0132\036.cash.z.wallet.sdk.rpc" + + ".BlockID\"V\n\010TxFilter\022-\n\005block\030\001 \001(\0132\036.ca" + + "sh.z.wallet.sdk.rpc.BlockID\022\r\n\005index\030\002 \001" + + "(\004\022\014\n\004hash\030\003 \001(\014\".\n\016RawTransaction\022\014\n\004da" + + "ta\030\001 \001(\014\022\016\n\006height\030\002 \001(\004\"7\n\014SendResponse" + + "\022\021\n\terrorCode\030\001 \001(\005\022\024\n\014errorMessage\030\002 \001(" + + "\t\"\013\n\tChainSpec\"\007\n\005Empty\"\272\002\n\nLightdInfo\022\017" + + "\n\007version\030\001 \001(\t\022\016\n\006vendor\030\002 \001(\t\022\024\n\014taddr" + + "Support\030\003 \001(\010\022\021\n\tchainName\030\004 \001(\t\022\037\n\027sapl" + + "ingActivationHeight\030\005 \001(\004\022\031\n\021consensusBr" + + "anchId\030\006 \001(\t\022\023\n\013blockHeight\030\007 \001(\004\022\021\n\tgit" + + "Commit\030\010 \001(\t\022\016\n\006branch\030\t \001(\t\022\021\n\tbuildDat" + + "e\030\n \001(\t\022\021\n\tbuildUser\030\013 \001(\t\022\027\n\017estimatedH" + + "eight\030\014 \001(\004\022\024\n\014piratedBuild\030\r \001(\t\022\031\n\021pir" + + "atedSubversion\030\016 \001(\t\"b\n\035TransparentAddre" + + "ssBlockFilter\022\017\n\007address\030\001 \001(\t\0220\n\005range\030" + + "\002 \001(\0132!.cash.z.wallet.sdk.rpc.BlockRange" + + "\"\036\n\010Duration\022\022\n\nintervalUs\030\001 \001(\003\"+\n\014Ping" + + "Response\022\r\n\005entry\030\001 \001(\003\022\014\n\004exit\030\002 \001(\003\"\032\n" + + "\007Address\022\017\n\007address\030\001 \001(\t\" \n\013AddressList" + + "\022\021\n\taddresses\030\001 \003(\t\"\033\n\007Balance\022\020\n\010valueZ" + + "at\030\001 \001(\003\"\027\n\007Exclude\022\014\n\004txid\030\001 \003(\014\"V\n\tTre" + + "eState\022\017\n\007network\030\001 \001(\t\022\016\n\006height\030\002 \001(\004\022" + + "\014\n\004hash\030\003 \001(\t\022\014\n\004time\030\004 \001(\r\022\014\n\004tree\030\005 \001(" + + "\t\"P\n\022GetAddressUtxosArg\022\021\n\taddresses\030\001 \003" + + "(\t\022\023\n\013startHeight\030\002 \001(\004\022\022\n\nmaxEntries\030\003 " + + "\001(\r\"v\n\024GetAddressUtxosReply\022\017\n\007address\030\006" + + " \001(\t\022\014\n\004txid\030\001 \001(\014\022\r\n\005index\030\002 \001(\005\022\016\n\006scr" + + "ipt\030\003 \001(\014\022\020\n\010valueZat\030\004 \001(\003\022\016\n\006height\030\005 " + + "\001(\004\"]\n\030GetAddressUtxosReplyList\022A\n\014addre" + + "ssUtxos\030\001 \003(\0132+.cash.z.wallet.sdk.rpc.Ge" + + "tAddressUtxosReply2\273\n\n\021CompactTxStreamer" + + "\022T\n\016GetLatestBlock\022 .cash.z.wallet.sdk.r" + + "pc.ChainSpec\032\036.cash.z.wallet.sdk.rpc.Blo" + + "ckID\"\000\022Q\n\010GetBlock\022\036.cash.z.wallet.sdk.r" + + "pc.BlockID\032#.cash.z.wallet.sdk.rpc.Compa" + + "ctBlock\"\000\022[\n\rGetBlockRange\022!.cash.z.wall" + + "et.sdk.rpc.BlockRange\032#.cash.z.wallet.sd" + + "k.rpc.CompactBlock\"\0000\001\022Z\n\016GetTransaction" + + "\022\037.cash.z.wallet.sdk.rpc.TxFilter\032%.cash" + + ".z.wallet.sdk.rpc.RawTransaction\"\000\022_\n\017Se" + + "ndTransaction\022%.cash.z.wallet.sdk.rpc.Ra" + + "wTransaction\032#.cash.z.wallet.sdk.rpc.Sen" + + "dResponse\"\000\022s\n\020GetTaddressTxids\0224.cash.z" + + ".wallet.sdk.rpc.TransparentAddressBlockF" + + "ilter\032%.cash.z.wallet.sdk.rpc.RawTransac" + + "tion\"\0000\001\022Z\n\022GetTaddressBalance\022\".cash.z." + + "wallet.sdk.rpc.AddressList\032\036.cash.z.wall" + + "et.sdk.rpc.Balance\"\000\022^\n\030GetTaddressBalan" + + "ceStream\022\036.cash.z.wallet.sdk.rpc.Address" + + "\032\036.cash.z.wallet.sdk.rpc.Balance\"\000(\001\022T\n\014" + + "GetMempoolTx\022\036.cash.z.wallet.sdk.rpc.Exc" + + "lude\032 .cash.z.wallet.sdk.rpc.CompactTx\"\000" + + "0\001\022R\n\014GetTreeState\022\036.cash.z.wallet.sdk.r" + + "pc.BlockID\032 .cash.z.wallet.sdk.rpc.TreeS" + + "tate\"\000\022o\n\017GetAddressUtxos\022).cash.z.walle" + + "t.sdk.rpc.GetAddressUtxosArg\032/.cash.z.wa" + + "llet.sdk.rpc.GetAddressUtxosReplyList\"\000\022" + + "s\n\025GetAddressUtxosStream\022).cash.z.wallet" + + ".sdk.rpc.GetAddressUtxosArg\032+.cash.z.wal" + + "let.sdk.rpc.GetAddressUtxosReply\"\0000\001\022R\n\r" + + "GetLightdInfo\022\034.cash.z.wallet.sdk.rpc.Em" + + "pty\032!.cash.z.wallet.sdk.rpc.LightdInfo\"\000" + + "\022N\n\004Ping\022\037.cash.z.wallet.sdk.rpc.Duratio" + + "n\032#.cash.z.wallet.sdk.rpc.PingResponse\"\000" + + "B\033Z\026lightwalletd/walletrpc\272\002\000b\006proto3" + }; + descriptor = com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + cash.z.wallet.sdk.rpc.CompactFormats.getDescriptor(), + }); + internal_static_cash_z_wallet_sdk_rpc_BlockID_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_cash_z_wallet_sdk_rpc_BlockID_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_BlockID_descriptor, + new java.lang.String[] { "Height", "Hash", }); + internal_static_cash_z_wallet_sdk_rpc_BlockRange_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_cash_z_wallet_sdk_rpc_BlockRange_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_BlockRange_descriptor, + new java.lang.String[] { "Start", "End", }); + internal_static_cash_z_wallet_sdk_rpc_TxFilter_descriptor = + getDescriptor().getMessageTypes().get(2); + internal_static_cash_z_wallet_sdk_rpc_TxFilter_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_TxFilter_descriptor, + new java.lang.String[] { "Block", "Index", "Hash", }); + internal_static_cash_z_wallet_sdk_rpc_RawTransaction_descriptor = + getDescriptor().getMessageTypes().get(3); + internal_static_cash_z_wallet_sdk_rpc_RawTransaction_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_RawTransaction_descriptor, + new java.lang.String[] { "Data", "Height", }); + internal_static_cash_z_wallet_sdk_rpc_SendResponse_descriptor = + getDescriptor().getMessageTypes().get(4); + internal_static_cash_z_wallet_sdk_rpc_SendResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_SendResponse_descriptor, + new java.lang.String[] { "ErrorCode", "ErrorMessage", }); + internal_static_cash_z_wallet_sdk_rpc_ChainSpec_descriptor = + getDescriptor().getMessageTypes().get(5); + internal_static_cash_z_wallet_sdk_rpc_ChainSpec_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_ChainSpec_descriptor, + new java.lang.String[] { }); + internal_static_cash_z_wallet_sdk_rpc_Empty_descriptor = + getDescriptor().getMessageTypes().get(6); + internal_static_cash_z_wallet_sdk_rpc_Empty_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_Empty_descriptor, + new java.lang.String[] { }); + internal_static_cash_z_wallet_sdk_rpc_LightdInfo_descriptor = + getDescriptor().getMessageTypes().get(7); + internal_static_cash_z_wallet_sdk_rpc_LightdInfo_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_LightdInfo_descriptor, + new java.lang.String[] { "Version", "Vendor", "TaddrSupport", "ChainName", "SaplingActivationHeight", "ConsensusBranchId", "BlockHeight", "GitCommit", "Branch", "BuildDate", "BuildUser", "EstimatedHeight", "PiratedBuild", "PiratedSubversion", }); + internal_static_cash_z_wallet_sdk_rpc_TransparentAddressBlockFilter_descriptor = + getDescriptor().getMessageTypes().get(8); + internal_static_cash_z_wallet_sdk_rpc_TransparentAddressBlockFilter_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_TransparentAddressBlockFilter_descriptor, + new java.lang.String[] { "Address", "Range", }); + internal_static_cash_z_wallet_sdk_rpc_Duration_descriptor = + getDescriptor().getMessageTypes().get(9); + internal_static_cash_z_wallet_sdk_rpc_Duration_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_Duration_descriptor, + new java.lang.String[] { "IntervalUs", }); + internal_static_cash_z_wallet_sdk_rpc_PingResponse_descriptor = + getDescriptor().getMessageTypes().get(10); + internal_static_cash_z_wallet_sdk_rpc_PingResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_PingResponse_descriptor, + new java.lang.String[] { "Entry", "Exit", }); + internal_static_cash_z_wallet_sdk_rpc_Address_descriptor = + getDescriptor().getMessageTypes().get(11); + internal_static_cash_z_wallet_sdk_rpc_Address_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_Address_descriptor, + new java.lang.String[] { "Address", }); + internal_static_cash_z_wallet_sdk_rpc_AddressList_descriptor = + getDescriptor().getMessageTypes().get(12); + internal_static_cash_z_wallet_sdk_rpc_AddressList_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_AddressList_descriptor, + new java.lang.String[] { "Addresses", }); + internal_static_cash_z_wallet_sdk_rpc_Balance_descriptor = + getDescriptor().getMessageTypes().get(13); + internal_static_cash_z_wallet_sdk_rpc_Balance_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_Balance_descriptor, + new java.lang.String[] { "ValueZat", }); + internal_static_cash_z_wallet_sdk_rpc_Exclude_descriptor = + getDescriptor().getMessageTypes().get(14); + internal_static_cash_z_wallet_sdk_rpc_Exclude_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_Exclude_descriptor, + new java.lang.String[] { "Txid", }); + internal_static_cash_z_wallet_sdk_rpc_TreeState_descriptor = + getDescriptor().getMessageTypes().get(15); + internal_static_cash_z_wallet_sdk_rpc_TreeState_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_TreeState_descriptor, + new java.lang.String[] { "Network", "Height", "Hash", "Time", "Tree", }); + internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosArg_descriptor = + getDescriptor().getMessageTypes().get(16); + internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosArg_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosArg_descriptor, + new java.lang.String[] { "Addresses", "StartHeight", "MaxEntries", }); + internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosReply_descriptor = + getDescriptor().getMessageTypes().get(17); + internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosReply_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosReply_descriptor, + new java.lang.String[] { "Address", "Txid", "Index", "Script", "ValueZat", "Height", }); + internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosReplyList_descriptor = + getDescriptor().getMessageTypes().get(18); + internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosReplyList_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_cash_z_wallet_sdk_rpc_GetAddressUtxosReplyList_descriptor, + new java.lang.String[] { "AddressUtxos", }); + cash.z.wallet.sdk.rpc.CompactFormats.getDescriptor(); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/src/main/java/com/rust/litewalletjni/LiteWalletJni.java b/src/main/java/com/rust/litewalletjni/LiteWalletJni.java new file mode 100644 index 00000000..3f1a506d --- /dev/null +++ b/src/main/java/com/rust/litewalletjni/LiteWalletJni.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * 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. + */ + +/* + * LiteWalletJni code based on https://github.com/PirateNetwork/cordova-plugin-litewallet + * + * MIT License + * + * Copyright (c) 2020 Zero Currency Coin + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.rust.litewalletjni; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.qortal.controller.PirateChainWalletController; + +import java.nio.file.Path; +import java.nio.file.Paths; + +public class LiteWalletJni { + + protected static final Logger LOGGER = LogManager.getLogger(LiteWalletJni.class); + + public static native String initlogging(); + public static native String initnew(final String serveruri, final String params, final String saplingOutputb64, final String saplingSpendb64); + public static native String initfromseed(final String serveruri, final String params, final String seed, final String birthday, final String saplingOutputb64, final String saplingSpendb64); + public static native String initfromb64(final String serveruri, final String params, final String datab64, final String saplingOutputb64, final String saplingSpendb64); + public static native String save(); + + public static native String execute(final String cmd, final String args); + public static native String getseedphrase(); + public static native String getseedphrasefromentropyb64(final String entropy64); + public static native String checkseedphrase(final String input); + + + private static boolean loaded = false; + + public static void loadLibrary() { + if (loaded) { + return; + } + String osName = System.getProperty("os.name"); + String osArchitecture = System.getProperty("os.arch"); + + LOGGER.info("OS Name: {}", osName); + LOGGER.info("OS Architecture: {}", osArchitecture); + + try { + String libFileName = PirateChainWalletController.getRustLibFilename(); + if (libFileName == null) { + LOGGER.info("Library not found for OS: {}, arch: {}", osName, osArchitecture); + return; + } + + Path libPath = Paths.get(PirateChainWalletController.getRustLibOuterDirectory().toString(), libFileName); + System.load(libPath.toAbsolutePath().toString()); + loaded = true; + } + catch (UnsatisfiedLinkError e) { + LOGGER.info("Unable to load library"); + } + } + + public static boolean isLoaded() { + return loaded; + } + +} diff --git a/src/main/java/org/qortal/api/model/crosschain/PirateChainSendRequest.java b/src/main/java/org/qortal/api/model/crosschain/PirateChainSendRequest.java new file mode 100644 index 00000000..e96bde01 --- /dev/null +++ b/src/main/java/org/qortal/api/model/crosschain/PirateChainSendRequest.java @@ -0,0 +1,32 @@ +package org.qortal.api.model.crosschain; + +import io.swagger.v3.oas.annotations.media.Schema; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +@XmlAccessorType(XmlAccessType.FIELD) +public class PirateChainSendRequest { + + @Schema(description = "32 bytes of entropy, Base58 encoded", example = "5oSXF53qENtdUyKhqSxYzP57m6RhVFP9BJKRr9E5kRGV") + public String entropy58; + + @Schema(description = "Recipient's Pirate Chain address", example = "zc...") + public String receivingAddress; + + @Schema(description = "Amount of ARRR to send", type = "number") + @XmlJavaTypeAdapter(value = org.qortal.api.AmountTypeAdapter.class) + public long arrrAmount; + + @Schema(description = "Transaction fee per byte (optional). Default is 0.00000100 ARRR (100 sats) per byte", example = "0.00000100", type = "number") + @XmlJavaTypeAdapter(value = org.qortal.api.AmountTypeAdapter.class) + public Long feePerByte; + + @Schema(description = "Optional memo to include information for the recipient", example = "zc...") + public String memo; + + public PirateChainSendRequest() { + } + +} diff --git a/src/main/java/org/qortal/api/resource/ArbitraryResource.java b/src/main/java/org/qortal/api/resource/ArbitraryResource.java index 451d9b8a..dad941e6 100644 --- a/src/main/java/org/qortal/api/resource/ArbitraryResource.java +++ b/src/main/java/org/qortal/api/resource/ArbitraryResource.java @@ -12,7 +12,6 @@ import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; import java.io.*; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; @@ -56,6 +55,7 @@ import org.qortal.transaction.Transaction.ValidationResult; import org.qortal.transform.TransformationException; import org.qortal.transform.transaction.ArbitraryTransactionTransformer; import org.qortal.transform.transaction.TransactionTransformer; +import org.qortal.utils.ArbitraryTransactionUtils; import org.qortal.utils.Base58; import org.qortal.utils.NTP; import org.qortal.utils.ZipUtils; @@ -254,7 +254,7 @@ public class ArbitraryResource { @QueryParam("build") Boolean build) { Security.requirePriorAuthorizationOrApiKey(request, name, service, null); - return this.getStatus(service, name, null, build); + return ArbitraryTransactionUtils.getStatus(service, name, null, build); } @GET @@ -276,7 +276,7 @@ public class ArbitraryResource { @QueryParam("build") Boolean build) { Security.requirePriorAuthorizationOrApiKey(request, name, service, identifier); - return this.getStatus(service, name, identifier, build); + return ArbitraryTransactionUtils.getStatus(service, name, identifier, build); } @@ -1247,24 +1247,6 @@ public class ArbitraryResource { } - private ArbitraryResourceStatus getStatus(Service service, String name, String identifier, Boolean build) { - - // If "build=true" has been specified in the query string, build the resource before returning its status - if (build != null && build == true) { - ArbitraryDataReader reader = new ArbitraryDataReader(name, ArbitraryDataFile.ResourceIdType.NAME, service, null); - try { - if (!reader.isBuilding()) { - reader.loadSynchronously(false); - } - } catch (Exception e) { - // No need to handle exception, as it will be reflected in the status - } - } - - ArbitraryDataResource resource = new ArbitraryDataResource(name, ResourceIdType.NAME, service, identifier); - return resource.getStatus(false); - } - private List addStatusToResources(List resources) { // Determine and add the status of each resource List updatedResources = new ArrayList<>(); diff --git a/src/main/java/org/qortal/api/resource/CrossChainHtlcResource.java b/src/main/java/org/qortal/api/resource/CrossChainHtlcResource.java index fbcde1a6..5c77f212 100644 --- a/src/main/java/org/qortal/api/resource/CrossChainHtlcResource.java +++ b/src/main/java/org/qortal/api/resource/CrossChainHtlcResource.java @@ -7,8 +7,11 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; +import java.io.IOException; import java.math.BigDecimal; import java.util.List; +import java.util.Objects; +import java.util.concurrent.locks.ReentrantLock; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.*; @@ -21,6 +24,7 @@ import org.bitcoinj.core.*; import org.bitcoinj.script.Script; import org.qortal.api.*; import org.qortal.api.model.CrossChainBitcoinyHTLCStatus; +import org.qortal.controller.Controller; import org.qortal.crosschain.*; import org.qortal.crypto.Crypto; import org.qortal.data.at.ATData; @@ -284,6 +288,12 @@ public class CrossChainHtlcResource { continue; } + Bitcoiny bitcoiny = (Bitcoiny) acct.getBlockchain(); + if (Objects.equals(bitcoiny.getCurrencyCode(), "ARRR")) { + LOGGER.info("Skipping AT {} because ARRR is currently unsupported", atAddress); + continue; + } + CrossChainTradeData crossChainTradeData = acct.populateTradeData(repository, atData); if (crossChainTradeData == null) { LOGGER.info("Couldn't find crosschain trade data for AT {}", atAddress); @@ -532,6 +542,11 @@ public class CrossChainHtlcResource { try { // Determine foreign blockchain receive address for refund Bitcoiny bitcoiny = (Bitcoiny) acct.getBlockchain(); + if (Objects.equals(bitcoiny.getCurrencyCode(), "ARRR")) { + LOGGER.info("Skipping AT {} because ARRR is currently unsupported", atAddress); + continue; + } + String receivingAddress = bitcoiny.getUnusedReceiveAddress(tradeBotData.getForeignKey()); LOGGER.info("Attempting to refund P2SH balance associated with AT {}...", atAddress); @@ -650,6 +665,48 @@ public class CrossChainHtlcResource { return false; } + @POST + @Path("/importarchivedtrades") + @Operation( + summary = "Imports archived trades from TradeBotStatesArchive.json", + description = "This can be used to recover trades that exist in the archive only, which may be needed if a
" + + "problem occurred during the proof-of-work computation stage of a buy request.", + responses = { + @ApiResponse( + content = @Content(mediaType = MediaType.TEXT_PLAIN, schema = @Schema(type = "boolean")) + ) + } + ) + @ApiErrors({ApiError.REPOSITORY_ISSUE}) + @SecurityRequirement(name = "apiKey") + public boolean importArchivedTrades(@HeaderParam(Security.API_KEY_HEADER) String apiKey) { + Security.checkApiCallAllowed(request); + + try (final Repository repository = RepositoryManager.getRepository()) { + ReentrantLock blockchainLock = Controller.getInstance().getBlockchainLock(); + + blockchainLock.lockInterruptibly(); + + try { + repository.importDataFromFile("qortal-backup/TradeBotStatesArchive.json"); + repository.saveChanges(); + + return true; + + } catch (IOException e) { + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_CRITERIA, e); + + } finally { + blockchainLock.unlock(); + } + } catch (InterruptedException e) { + // We couldn't lock blockchain to perform import + return false; + } catch (DataException e) { + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e); + } + } + private long calcFeeTimestamp(int lockTimeA, int tradeTimeout) { return (lockTimeA - tradeTimeout * 60) * 1000L; } diff --git a/src/main/java/org/qortal/api/resource/CrossChainPirateChainResource.java b/src/main/java/org/qortal/api/resource/CrossChainPirateChainResource.java new file mode 100644 index 00000000..bd7bf57d --- /dev/null +++ b/src/main/java/org/qortal/api/resource/CrossChainPirateChainResource.java @@ -0,0 +1,229 @@ +package org.qortal.api.resource; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.parameters.RequestBody; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.qortal.api.ApiError; +import org.qortal.api.ApiErrors; +import org.qortal.api.ApiExceptionFactory; +import org.qortal.api.Security; +import org.qortal.api.model.crosschain.PirateChainSendRequest; +import org.qortal.crosschain.ForeignBlockchainException; +import org.qortal.crosschain.PirateChain; +import org.qortal.crosschain.SimpleTransaction; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import java.util.List; + +@Path("/crosschain/arrr") +@Tag(name = "Cross-Chain (Pirate Chain)") +public class CrossChainPirateChainResource { + + @Context + HttpServletRequest request; + + @POST + @Path("/walletbalance") + @Operation( + summary = "Returns ARRR balance", + description = "Supply 32 bytes of entropy, Base58 encoded", + requestBody = @RequestBody( + required = true, + content = @Content( + mediaType = MediaType.TEXT_PLAIN, + schema = @Schema( + type = "string", + description = "32 bytes of entropy, Base58 encoded", + example = "5oSXF53qENtdUyKhqSxYzP57m6RhVFP9BJKRr9E5kRGV" + ) + ) + ), + responses = { + @ApiResponse( + content = @Content(mediaType = MediaType.TEXT_PLAIN, schema = @Schema(type = "string", description = "balance (satoshis)")) + ) + } + ) + @ApiErrors({ApiError.INVALID_PRIVATE_KEY, ApiError.FOREIGN_BLOCKCHAIN_NETWORK_ISSUE}) + @SecurityRequirement(name = "apiKey") + public String getPirateChainWalletBalance(@HeaderParam(Security.API_KEY_HEADER) String apiKey, String entropy58) { + Security.checkApiCallAllowed(request); + + PirateChain pirateChain = PirateChain.getInstance(); + + try { + Long balance = pirateChain.getWalletBalance(entropy58); + if (balance == null) + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.FOREIGN_BLOCKCHAIN_NETWORK_ISSUE); + + return balance.toString(); + + } catch (ForeignBlockchainException e) { + throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.FOREIGN_BLOCKCHAIN_NETWORK_ISSUE, e.getMessage()); + } + } + + @POST + @Path("/wallettransactions") + @Operation( + summary = "Returns transactions", + description = "Supply 32 bytes of entropy, Base58 encoded", + requestBody = @RequestBody( + required = true, + content = @Content( + mediaType = MediaType.TEXT_PLAIN, + schema = @Schema( + type = "string", + description = "32 bytes of entropy, Base58 encoded", + example = "5oSXF53qENtdUyKhqSxYzP57m6RhVFP9BJKRr9E5kRGV" + ) + ) + ), + responses = { + @ApiResponse( + content = @Content(array = @ArraySchema( schema = @Schema( implementation = SimpleTransaction.class ) ) ) + ) + } + ) + @ApiErrors({ApiError.INVALID_PRIVATE_KEY, ApiError.FOREIGN_BLOCKCHAIN_NETWORK_ISSUE}) + @SecurityRequirement(name = "apiKey") + public List getPirateChainWalletTransactions(@HeaderParam(Security.API_KEY_HEADER) String apiKey, String entropy58) { + Security.checkApiCallAllowed(request); + + PirateChain pirateChain = PirateChain.getInstance(); + + try { + return pirateChain.getWalletTransactions(entropy58); + } catch (ForeignBlockchainException e) { + throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.FOREIGN_BLOCKCHAIN_NETWORK_ISSUE, e.getMessage()); + } + } + + @POST + @Path("/send") + @Operation( + summary = "Sends ARRR from wallet", + description = "Currently supports 'legacy' P2PKH PirateChain addresses and Native SegWit (P2WPKH) addresses. Supply BIP32 'm' private key in base58, starting with 'xprv' for mainnet, 'tprv' for testnet", + requestBody = @RequestBody( + required = true, + content = @Content( + mediaType = MediaType.TEXT_PLAIN, + schema = @Schema( + type = "string", + description = "32 bytes of entropy, Base58 encoded", + example = "5oSXF53qENtdUyKhqSxYzP57m6RhVFP9BJKRr9E5kRGV" + ) + ) + ), + responses = { + @ApiResponse( + content = @Content(mediaType = MediaType.TEXT_PLAIN, schema = @Schema(type = "string", description = "transaction hash")) + ) + } + ) + @ApiErrors({ApiError.INVALID_PRIVATE_KEY, ApiError.INVALID_CRITERIA, ApiError.INVALID_ADDRESS, ApiError.FOREIGN_BLOCKCHAIN_BALANCE_ISSUE, ApiError.FOREIGN_BLOCKCHAIN_NETWORK_ISSUE}) + @SecurityRequirement(name = "apiKey") + public String sendBitcoin(@HeaderParam(Security.API_KEY_HEADER) String apiKey, PirateChainSendRequest pirateChainSendRequest) { + Security.checkApiCallAllowed(request); + + if (pirateChainSendRequest.arrrAmount <= 0) + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_CRITERIA); + + if (pirateChainSendRequest.feePerByte != null && pirateChainSendRequest.feePerByte <= 0) + throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_CRITERIA); + + PirateChain pirateChain = PirateChain.getInstance(); + + try { + return pirateChain.sendCoins(pirateChainSendRequest); + + } catch (ForeignBlockchainException e) { + // TODO + throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.FOREIGN_BLOCKCHAIN_NETWORK_ISSUE, e.getMessage()); + } + } + + + @POST + @Path("/walletaddress") + @Operation( + summary = "Returns main wallet address", + description = "Supply 32 bytes of entropy, Base58 encoded", + requestBody = @RequestBody( + required = true, + content = @Content( + mediaType = MediaType.TEXT_PLAIN, + schema = @Schema( + type = "string", + description = "32 bytes of entropy, Base58 encoded", + example = "5oSXF53qENtdUyKhqSxYzP57m6RhVFP9BJKRr9E5kRGV" + ) + ) + ), + responses = { + @ApiResponse( + content = @Content(array = @ArraySchema( schema = @Schema( implementation = SimpleTransaction.class ) ) ) + ) + } + ) + @ApiErrors({ApiError.INVALID_PRIVATE_KEY, ApiError.FOREIGN_BLOCKCHAIN_NETWORK_ISSUE}) + @SecurityRequirement(name = "apiKey") + public String getPirateChainWalletAddress(@HeaderParam(Security.API_KEY_HEADER) String apiKey, String entropy58) { + Security.checkApiCallAllowed(request); + + PirateChain pirateChain = PirateChain.getInstance(); + + try { + return pirateChain.getWalletAddress(entropy58); + } catch (ForeignBlockchainException e) { + throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.FOREIGN_BLOCKCHAIN_NETWORK_ISSUE, e.getMessage()); + } + } + + + @POST + @Path("/syncstatus") + @Operation( + summary = "Returns synchronization status", + description = "Supply 32 bytes of entropy, Base58 encoded", + requestBody = @RequestBody( + required = true, + content = @Content( + mediaType = MediaType.TEXT_PLAIN, + schema = @Schema( + type = "string", + description = "32 bytes of entropy, Base58 encoded", + example = "5oSXF53qENtdUyKhqSxYzP57m6RhVFP9BJKRr9E5kRGV" + ) + ) + ), + responses = { + @ApiResponse( + content = @Content(array = @ArraySchema( schema = @Schema( implementation = SimpleTransaction.class ) ) ) + ) + } + ) + @ApiErrors({ApiError.INVALID_PRIVATE_KEY, ApiError.FOREIGN_BLOCKCHAIN_NETWORK_ISSUE}) + @SecurityRequirement(name = "apiKey") + public String getPirateChainSyncStatus(@HeaderParam(Security.API_KEY_HEADER) String apiKey, String entropy58) { + Security.checkApiCallAllowed(request); + + PirateChain pirateChain = PirateChain.getInstance(); + + try { + return pirateChain.getSyncStatus(entropy58); + } catch (ForeignBlockchainException e) { + throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.FOREIGN_BLOCKCHAIN_NETWORK_ISSUE, e.getMessage()); + } + } +} diff --git a/src/main/java/org/qortal/api/resource/CrossChainTradeBotResource.java b/src/main/java/org/qortal/api/resource/CrossChainTradeBotResource.java index 66800eb7..3c8bd28f 100644 --- a/src/main/java/org/qortal/api/resource/CrossChainTradeBotResource.java +++ b/src/main/java/org/qortal/api/resource/CrossChainTradeBotResource.java @@ -155,7 +155,7 @@ public class CrossChainTradeBotResource { return Base58.encode(unsignedBytes); } catch (DataException e) { - throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e); + throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.REPOSITORY_ISSUE, e.getMessage()); } } @@ -240,7 +240,7 @@ public class CrossChainTradeBotResource { return "false"; } } catch (DataException e) { - throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e); + throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.REPOSITORY_ISSUE, e.getMessage()); } } diff --git a/src/main/java/org/qortal/api/resource/TransactionsResource.java b/src/main/java/org/qortal/api/resource/TransactionsResource.java index 75724310..2b9b28a1 100644 --- a/src/main/java/org/qortal/api/resource/TransactionsResource.java +++ b/src/main/java/org/qortal/api/resource/TransactionsResource.java @@ -748,7 +748,7 @@ public class TransactionsResource { throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.INVALID_SIGNATURE); ReentrantLock blockchainLock = Controller.getInstance().getBlockchainLock(); - if (!blockchainLock.tryLock(30, TimeUnit.SECONDS)) + if (!blockchainLock.tryLock(60, TimeUnit.SECONDS)) throw createTransactionInvalidException(request, ValidationResult.NO_BLOCKCHAIN_LOCK); try { diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataReader.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataReader.java index 568549d8..5d4b015c 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataReader.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataReader.java @@ -170,6 +170,7 @@ public class ArbitraryDataReader { this.validate(); } catch (DataException e) { + LOGGER.info("DataException when trying to load QDN resource", e); this.deleteWorkingDirectory(); throw new DataException(e.getMessage()); @@ -208,8 +209,13 @@ public class ArbitraryDataReader { * serve a cached version of the resource for subsequent requests. * @throws IOException */ - private void deleteWorkingDirectory() throws IOException { - FilesystemUtils.safeDeleteDirectory(this.workingPath, true); + private void deleteWorkingDirectory() { + try { + FilesystemUtils.safeDeleteDirectory(this.workingPath, true); + } catch (IOException e) { + // Ignore failures as this isn't an essential step + LOGGER.info("Unable to delete working path {}: {}", this.workingPath, e.getMessage()); + } } private void createUncompressedDirectory() throws DataException { @@ -408,6 +414,7 @@ public class ArbitraryDataReader { this.decryptUsingAlgo("AES/CBC/PKCS5Padding"); } catch (DataException e) { + LOGGER.info("Unable to decrypt using specific parameters: {}", e.getMessage()); // Something went wrong, so fall back to default AES params (necessary for legacy resource support) this.decryptUsingAlgo("AES"); @@ -420,8 +427,9 @@ public class ArbitraryDataReader { byte[] secret = this.secret58 != null ? Base58.decode(this.secret58) : null; if (secret != null && secret.length == Transformer.AES256_LENGTH) { try { + LOGGER.info("Decrypting using algorithm {}...", algorithm); Path unencryptedPath = Paths.get(this.workingPath.toString(), "zipped.zip"); - SecretKey aesKey = new SecretKeySpec(secret, 0, secret.length, algorithm); + SecretKey aesKey = new SecretKeySpec(secret, 0, secret.length, "AES"); AES.decryptFile(algorithm, aesKey, this.filePath.toString(), unencryptedPath.toString()); // Replace filePath pointer with the encrypted file path @@ -430,7 +438,8 @@ public class ArbitraryDataReader { } catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException | IOException | InvalidKeyException e) { - throw new DataException(String.format("Unable to decrypt file at path %s: %s", this.filePath, e.getMessage())); + LOGGER.info(String.format("Exception when decrypting using algorithm %s", algorithm), e); + throw new DataException(String.format("Unable to decrypt file at path %s using algorithm %s: %s", this.filePath, algorithm, e.getMessage())); } } else { // Assume it is unencrypted. This will be the case when we have built a custom path by combining @@ -477,7 +486,12 @@ public class ArbitraryDataReader { // Delete original compressed file if (FilesystemUtils.pathInsideDataOrTempPath(this.filePath)) { if (Files.exists(this.filePath)) { - Files.delete(this.filePath); + try { + Files.delete(this.filePath); + } catch (IOException e) { + // Ignore failures as this isn't an essential step + LOGGER.info("Unable to delete file at path {}", this.filePath); + } } } diff --git a/src/main/java/org/qortal/block/Block.java b/src/main/java/org/qortal/block/Block.java index d0f742fd..c81eef8a 100644 --- a/src/main/java/org/qortal/block/Block.java +++ b/src/main/java/org/qortal/block/Block.java @@ -199,6 +199,11 @@ public class Block { } + public boolean hasShareBin(AccountLevelShareBin shareBin, int blockHeight) { + AccountLevelShareBin ourShareBin = this.getShareBin(blockHeight); + return ourShareBin != null && shareBin.id == ourShareBin.id; + } + public long distribute(long accountAmount, Map balanceChanges) { if (this.isRecipientAlsoMinter) { // minter & recipient the same - simpler case @@ -1238,6 +1243,7 @@ public class Block { } } } catch (DataException e) { + LOGGER.info("DataException during transaction validation", e); return ValidationResult.TRANSACTION_INVALID; } finally { // Rollback repository changes made by test-processing transactions above @@ -1914,12 +1920,67 @@ public class Block { final boolean haveFounders = !onlineFounderAccounts.isEmpty(); // Determine reward candidates based on account level - List accountLevelShareBins = BlockChain.getInstance().getAccountLevelShareBins(); - for (int binIndex = 0; binIndex < accountLevelShareBins.size(); ++binIndex) { - // Find all accounts in share bin. getShareBin() returns null for minter accounts that are also founders, so they are effectively filtered out. + // This needs a deep copy, so the shares can be modified when tiers aren't activated yet + List accountLevelShareBins = new ArrayList<>(); + for (AccountLevelShareBin accountLevelShareBin : BlockChain.getInstance().getAccountLevelShareBins()) { + accountLevelShareBins.add((AccountLevelShareBin) accountLevelShareBin.clone()); + } + + Map> accountsForShareBin = new HashMap<>(); + + // We might need to combine some share bins if they haven't reached the minimum number of minters yet + for (int binIndex = accountLevelShareBins.size()-1; binIndex >= 0; --binIndex) { AccountLevelShareBin accountLevelShareBin = accountLevelShareBins.get(binIndex); - // Object reference compare is OK as all references are read-only from blockchain config. - List binnedAccounts = expandedAccounts.stream().filter(accountInfo -> accountInfo.getShareBin(this.blockData.getHeight()) == accountLevelShareBin).collect(Collectors.toList()); + + // Find all accounts in share bin. getShareBin() returns null for minter accounts that are also founders, so they are effectively filtered out. + List binnedAccounts = expandedAccounts.stream().filter(accountInfo -> accountInfo.hasShareBin(accountLevelShareBin, this.blockData.getHeight())).collect(Collectors.toList()); + // Add any accounts that have been moved down from a higher tier + List existingBinnedAccounts = accountsForShareBin.get(binIndex); + if (existingBinnedAccounts != null) + binnedAccounts.addAll(existingBinnedAccounts); + + // Logic below may only apply to higher levels, and only for share bins with a specific range of online accounts + if (accountLevelShareBin.levels.get(0) < BlockChain.getInstance().getShareBinActivationMinLevel() || + binnedAccounts.isEmpty() || binnedAccounts.size() >= BlockChain.getInstance().getMinAccountsToActivateShareBin()) { + // Add all accounts for this share bin to the accountsForShareBin list + accountsForShareBin.put(binIndex, binnedAccounts); + continue; + } + + // Share bin contains more than one, but less than the minimum number of minters. We treat this share bin + // as not activated yet. In these cases, the rewards and minters are combined and paid out to the previous + // share bin, to prevent a single or handful of accounts receiving the entire rewards for a share bin. + // + // Example: + // + // - Share bin for levels 5 and 6 has 100 minters + // - Share bin for levels 7 and 8 has 10 minters + // + // This is below the minimum of 30, so share bins are reconstructed as follows: + // + // - Share bin for levels 5 and 6 now contains 110 minters + // - Share bin for levels 7 and 8 now contains 0 minters + // - Share bin for levels 5 and 6 now pays out rewards for levels 5, 6, 7, and 8 + // - Share bin for levels 7 and 8 pays zero rewards + // + // This process is iterative, so will combine several tiers if needed. + + // Designate this share bin as empty + accountsForShareBin.put(binIndex, new ArrayList<>()); + + // Move the accounts originally intended for this share bin to the previous one + accountsForShareBin.put(binIndex - 1, binnedAccounts); + + // Move the block reward from this share bin to the previous one + AccountLevelShareBin previousShareBin = accountLevelShareBins.get(binIndex - 1); + previousShareBin.share += accountLevelShareBin.share; + accountLevelShareBin.share = 0L; + } + + // Now loop through (potentially modified) share bins and determine the reward candidates + for (int binIndex = 0; binIndex < accountLevelShareBins.size(); ++binIndex) { + AccountLevelShareBin accountLevelShareBin = accountLevelShareBins.get(binIndex); + List binnedAccounts = accountsForShareBin.get(binIndex); // No online accounts in this bin? Skip to next one if (binnedAccounts.isEmpty()) diff --git a/src/main/java/org/qortal/block/BlockChain.java b/src/main/java/org/qortal/block/BlockChain.java index 0e746766..59b71e3c 100644 --- a/src/main/java/org/qortal/block/BlockChain.java +++ b/src/main/java/org/qortal/block/BlockChain.java @@ -103,10 +103,23 @@ public class BlockChain { private List rewardsByHeight; /** Share of block reward/fees by account level */ - public static class AccountLevelShareBin { + public static class AccountLevelShareBin implements Cloneable { + public int id; public List levels; @XmlJavaTypeAdapter(value = org.qortal.api.AmountTypeAdapter.class) public long share; + + public Object clone() { + AccountLevelShareBin shareBinCopy = new AccountLevelShareBin(); + List levelsCopy = new ArrayList<>(); + for (Integer level : this.levels) { + levelsCopy.add(level); + } + shareBinCopy.id = this.id; + shareBinCopy.levels = levelsCopy; + shareBinCopy.share = this.share; + return shareBinCopy; + } } private List sharesByLevel; /** Generated lookup of share-bin by account level */ @@ -120,6 +133,12 @@ public class BlockChain { @XmlJavaTypeAdapter(value = org.qortal.api.AmountTypeAdapter.class) private Long qoraPerQortReward; + /** Minimum number of accounts before a share bin is considered activated */ + private int minAccountsToActivateShareBin; + + /** Min level at which share bin activation takes place; lower levels allow less than minAccountsPerShareBin */ + private int shareBinActivationMinLevel; + /** * Number of minted blocks required to reach next level from previous. *

@@ -378,6 +397,14 @@ public class BlockChain { return this.qoraPerQortReward; } + public int getMinAccountsToActivateShareBin() { + return this.minAccountsToActivateShareBin; + } + + public int getShareBinActivationMinLevel() { + return this.shareBinActivationMinLevel; + } + public int getMinAccountLevelToMint() { return this.minAccountLevelToMint; } diff --git a/src/main/java/org/qortal/controller/BlockMinter.java b/src/main/java/org/qortal/controller/BlockMinter.java index 2d736e76..343ab4af 100644 --- a/src/main/java/org/qortal/controller/BlockMinter.java +++ b/src/main/java/org/qortal/controller/BlockMinter.java @@ -90,37 +90,40 @@ public class BlockMinter extends Thread { List newBlocks = new ArrayList<>(); - // Flags for tracking change in whether minting is possible, - // so we can notify Controller, and further update SysTray, etc. - boolean isMintingPossible = false; - boolean wasMintingPossible = isMintingPossible; - while (running) { - if (isMintingPossible != wasMintingPossible) - Controller.getInstance().onMintingPossibleChange(isMintingPossible); + try (final Repository repository = RepositoryManager.getRepository()) { + // Going to need this a lot... + BlockRepository blockRepository = repository.getBlockRepository(); - wasMintingPossible = isMintingPossible; + // Flags for tracking change in whether minting is possible, + // so we can notify Controller, and further update SysTray, etc. + boolean isMintingPossible = false; + boolean wasMintingPossible = isMintingPossible; + while (running) { + if (isMintingPossible != wasMintingPossible) + Controller.getInstance().onMintingPossibleChange(isMintingPossible); - try { - // Sleep for a while - Thread.sleep(1000); + wasMintingPossible = isMintingPossible; - isMintingPossible = false; + try { + // Free up any repository locks + repository.discardChanges(); - final Long now = NTP.getTime(); - if (now == null) - continue; + // Sleep for a while + Thread.sleep(1000); - final Long minLatestBlockTimestamp = Controller.getMinimumLatestBlockTimestamp(); - if (minLatestBlockTimestamp == null) - continue; + isMintingPossible = false; - // No online accounts for current timestamp? (e.g. during startup) - if (!OnlineAccountsManager.getInstance().hasOnlineAccounts()) - continue; + final Long now = NTP.getTime(); + if (now == null) + continue; - try (final Repository repository = RepositoryManager.getRepository()) { - // Going to need this a lot... - BlockRepository blockRepository = repository.getBlockRepository(); + final Long minLatestBlockTimestamp = Controller.getMinimumLatestBlockTimestamp(); + if (minLatestBlockTimestamp == null) + continue; + + // No online accounts for current timestamp? (e.g. during startup) + if (!OnlineAccountsManager.getInstance().hasOnlineAccounts()) + continue; List mintingAccountsData = repository.getAccountRepository().getMintingAccounts(); // No minting accounts? @@ -198,10 +201,6 @@ public class BlockMinter extends Thread { // so go ahead and mint a block if possible. isMintingPossible = true; - // Reattach newBlocks to new repository handle - for (Block newBlock : newBlocks) - newBlock.setRepository(repository); - // Check blockchain hasn't changed if (previousBlockData == null || !Arrays.equals(previousBlockData.getSignature(), lastBlockData.getSignature())) { previousBlockData = lastBlockData; @@ -439,13 +438,13 @@ public class BlockMinter extends Thread { Network network = Network.getInstance(); network.broadcast(broadcastPeer -> network.buildHeightMessage(broadcastPeer, newBlockData)); } - } catch (DataException e) { - LOGGER.warn("Repository issue while running block minter", e); + } catch (InterruptedException e) { + // We've been interrupted - time to exit + return; } - } catch (InterruptedException e) { - // We've been interrupted - time to exit - return; } + } catch (DataException e) { + LOGGER.warn("Repository issue while running block minter - NO LONGER MINTING", e); } } diff --git a/src/main/java/org/qortal/controller/Controller.java b/src/main/java/org/qortal/controller/Controller.java index 727fdd89..4ff08e15 100644 --- a/src/main/java/org/qortal/controller/Controller.java +++ b/src/main/java/org/qortal/controller/Controller.java @@ -497,6 +497,9 @@ public class Controller extends Thread { AutoUpdate.getInstance().start(); } + LOGGER.info("Starting wallets"); + PirateChainWalletController.getInstance().start(); + LOGGER.info(String.format("Starting API on port %d", Settings.getInstance().getApiPort())); try { ApiService apiService = ApiService.getInstance(); @@ -890,6 +893,9 @@ public class Controller extends Thread { LOGGER.info("Shutting down API"); ApiService.getInstance().stop(); + LOGGER.info("Shutting down wallets"); + PirateChainWalletController.getInstance().shutdown(); + if (Settings.getInstance().isAutoUpdateEnabled()) { LOGGER.info("Shutting down auto-update"); AutoUpdate.getInstance().shutdown(); diff --git a/src/main/java/org/qortal/controller/OnlineAccountsManager.java b/src/main/java/org/qortal/controller/OnlineAccountsManager.java index 9cfae61d..05f353e8 100644 --- a/src/main/java/org/qortal/controller/OnlineAccountsManager.java +++ b/src/main/java/org/qortal/controller/OnlineAccountsManager.java @@ -275,6 +275,12 @@ public class OnlineAccountsManager { return false; } + // Check timestamp is a multiple of online timestamp modulus + if (onlineAccountTimestamp % getOnlineTimestampModulus() != 0) { + LOGGER.trace(() -> String.format("Rejecting online account %s with invalid timestamp %d", Base58.encode(rewardSharePublicKey), onlineAccountTimestamp)); + return false; + } + // Verify signature byte[] data = Longs.toByteArray(onlineAccountData.getTimestamp()); boolean isSignatureValid = Qortal25519Extras.verifyAggregated(rewardSharePublicKey, onlineAccountData.getSignature(), data); diff --git a/src/main/java/org/qortal/controller/PirateChainWalletController.java b/src/main/java/org/qortal/controller/PirateChainWalletController.java new file mode 100644 index 00000000..931850db --- /dev/null +++ b/src/main/java/org/qortal/controller/PirateChainWalletController.java @@ -0,0 +1,398 @@ +package org.qortal.controller; + +import com.rust.litewalletjni.LiteWalletJni; +import org.apache.commons.io.FileUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.json.JSONObject; +import org.qortal.arbitrary.ArbitraryDataFile; +import org.qortal.arbitrary.ArbitraryDataReader; +import org.qortal.arbitrary.ArbitraryDataResource; +import org.qortal.arbitrary.exception.MissingDataException; +import org.qortal.crosschain.ForeignBlockchainException; +import org.qortal.crosschain.PirateWallet; +import org.qortal.data.arbitrary.ArbitraryResourceStatus; +import org.qortal.data.transaction.ArbitraryTransactionData; +import org.qortal.data.transaction.TransactionData; +import org.qortal.network.Network; +import org.qortal.network.Peer; +import org.qortal.repository.DataException; +import org.qortal.repository.Repository; +import org.qortal.repository.RepositoryManager; +import org.qortal.settings.Settings; +import org.qortal.transaction.ArbitraryTransaction; +import org.qortal.utils.ArbitraryTransactionUtils; +import org.qortal.utils.Base58; +import org.qortal.utils.FilesystemUtils; +import org.qortal.utils.NTP; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.Objects; + +public class PirateChainWalletController extends Thread { + + protected static final Logger LOGGER = LogManager.getLogger(PirateChainWalletController.class); + + private static PirateChainWalletController instance; + + final private static long SAVE_INTERVAL = 60 * 60 * 1000L; // 1 hour + private long lastSaveTime = 0L; + + private boolean running; + private PirateWallet currentWallet = null; + private boolean shouldLoadWallet = false; + private String loadStatus = null; + + private static String qdnWalletSignature = "EsfUw54perxkEtfoUoL7Z97XPrNsZRZXePVZPz3cwRm9qyEPSofD5KmgVpDqVitQp7LhnZRmL6z2V9hEe1YS45T"; + + + private PirateChainWalletController() { + this.running = true; + } + + public static PirateChainWalletController getInstance() { + if (instance == null) + instance = new PirateChainWalletController(); + + return instance; + } + + @Override + public void run() { + Thread.currentThread().setName("Pirate Chain Wallet Controller"); + + try { + while (running && !Controller.isStopping()) { + Thread.sleep(1000); + + // Wait until we have a request to load the wallet + if (!shouldLoadWallet) { + continue; + } + + if (!LiteWalletJni.isLoaded()) { + this.loadLibrary(); + + // If still not loaded, sleep to prevent too many requests + if (!LiteWalletJni.isLoaded()) { + Thread.sleep(5 * 1000); + continue; + } + } + + // Wallet is downloaded, so clear the status + this.loadStatus = null; + + if (this.currentWallet == null) { + // Nothing to do yet + continue; + } + if (this.currentWallet.isNullSeedWallet()) { + // Don't sync the null seed wallet + continue; + } + + LOGGER.debug("Syncing Pirate Chain wallet..."); + String response = LiteWalletJni.execute("sync", ""); + LOGGER.debug("sync response: {}", response); + JSONObject json = new JSONObject(response); + if (json.has("result")) { + String result = json.getString("result"); + + // We may have to set wallet to ready if this is the first ever successful sync + if (Objects.equals(result, "success")) { + this.currentWallet.setReady(true); + } + } + + // Rate limit sync attempts + Thread.sleep(30000); + + // Save wallet if needed + Long now = NTP.getTime(); + if (now != null && now-SAVE_INTERVAL >= this.lastSaveTime) { + this.saveCurrentWallet(); + } + } + } catch (InterruptedException e) { + // Fall-through to exit + } + } + + public void shutdown() { + // Save the wallet + this.saveCurrentWallet(); + + this.running = false; + this.interrupt(); + } + + + // QDN & wallet libraries + + private void loadLibrary() throws InterruptedException { + try (final Repository repository = RepositoryManager.getRepository()) { + + // Check if architecture is supported + String libFileName = PirateChainWalletController.getRustLibFilename(); + if (libFileName == null) { + String osName = System.getProperty("os.name"); + String osArchitecture = System.getProperty("os.arch"); + this.loadStatus = String.format("Unsupported architecture (%s %s)", osName, osArchitecture); + return; + } + + // Check if the library exists in the wallets folder + Path libDirectory = PirateChainWalletController.getRustLibOuterDirectory(); + Path libPath = Paths.get(libDirectory.toString(), libFileName); + if (Files.exists(libPath)) { + // Already downloaded; we can load the library right away + LiteWalletJni.loadLibrary(); + return; + } + + // Library not found, so check if we've fetched the resource from QDN + ArbitraryTransactionData t = this.getTransactionData(repository); + if (t == null) { + // Can't find the transaction - maybe on a different chain? + return; + } + + // Wait until we have a sufficient number of peers to attempt QDN downloads + List handshakedPeers = Network.getInstance().getImmutableHandshakedPeers(); + if (handshakedPeers.size() < Settings.getInstance().getMinBlockchainPeers()) { + // Wait for more peers + this.loadStatus = String.format("Searching for peers..."); + return; + } + + // Build resource + ArbitraryDataReader arbitraryDataReader = new ArbitraryDataReader(t.getName(), + ArbitraryDataFile.ResourceIdType.NAME, t.getService(), t.getIdentifier()); + try { + arbitraryDataReader.loadSynchronously(false); + } catch (MissingDataException e) { + LOGGER.info("Missing data when loading Pirate Chain library"); + } + + // Check its status + ArbitraryResourceStatus status = ArbitraryTransactionUtils.getStatus( + t.getService(), t.getName(), t.getIdentifier(), false); + + if (status.getStatus() != ArbitraryResourceStatus.Status.READY) { + LOGGER.info("Not ready yet: {}", status.getTitle()); + this.loadStatus = String.format("Downloading files from QDN... (%d / %d)", status.getLocalChunkCount(), status.getTotalChunkCount()); + return; + } + + // Files are downloaded, so copy the necessary files to the wallets folder + // Delete the wallets/*/lib directory first, in case earlier versions of the wallet are present + Path walletsLibDirectory = PirateChainWalletController.getWalletsLibDirectory(); + if (Files.exists(walletsLibDirectory)) { + FilesystemUtils.safeDeleteDirectory(walletsLibDirectory, false); + } + Files.createDirectories(libDirectory); + FileUtils.copyDirectory(arbitraryDataReader.getFilePath().toFile(), libDirectory.toFile()); + + // Clear reader cache so only one copy exists + ArbitraryDataResource resource = new ArbitraryDataResource(t.getName(), + ArbitraryDataFile.ResourceIdType.NAME, t.getService(), t.getIdentifier()); + resource.deleteCache(); + + // Finally, load the library + LiteWalletJni.loadLibrary(); + + } catch (DataException e) { + LOGGER.error("Repository issue when loading Pirate Chain library", e); + } catch (IOException e) { + LOGGER.error("Error when loading Pirate Chain library", e); + } + } + + private ArbitraryTransactionData getTransactionData(Repository repository) { + try { + byte[] signature = Base58.decode(qdnWalletSignature); + TransactionData transactionData = repository.getTransactionRepository().fromSignature(signature); + if (!(transactionData instanceof ArbitraryTransactionData)) + return null; + + ArbitraryTransaction arbitraryTransaction = new ArbitraryTransaction(repository, transactionData); + if (arbitraryTransaction != null) { + return (ArbitraryTransactionData) arbitraryTransaction.getTransactionData(); + } + + return null; + } catch (DataException e) { + return null; + } + } + + public static String getRustLibFilename() { + String osName = System.getProperty("os.name"); + String osArchitecture = System.getProperty("os.arch"); + + if (osName.equals("Mac OS X") && osArchitecture.equals("x86_64")) { + return "librust-macos-x86_64.dylib"; + } + else if (osName.equals("Linux") && osArchitecture.equals("aarch64")) { + return "librust-linux-aarch64.so"; + } + else if (osName.equals("Linux") && osArchitecture.equals("amd64")) { + return "librust-linux-x86_64.so"; + } + else if (osName.contains("Windows") && osArchitecture.equals("amd64")) { + return "librust-windows-x86_64.dll"; + } + + return null; + } + + public static Path getWalletsLibDirectory() { + return Paths.get(Settings.getInstance().getWalletsPath(), "PirateChain", "lib"); + } + + public static Path getRustLibOuterDirectory() { + String sigPrefix = qdnWalletSignature.substring(0, 8); + return Paths.get(Settings.getInstance().getWalletsPath(), "PirateChain", "lib", sigPrefix); + } + + + // Wallet functions + + public boolean initWithEntropy58(String entropy58) { + return this.initWithEntropy58(entropy58, false); + } + + public boolean initNullSeedWallet() { + return this.initWithEntropy58(Base58.encode(new byte[32]), true); + } + + private boolean initWithEntropy58(String entropy58, boolean isNullSeedWallet) { + // If the JNI library isn't loaded yet then we can't proceed + if (!LiteWalletJni.isLoaded()) { + shouldLoadWallet = true; + return false; + } + + byte[] entropyBytes = Base58.decode(entropy58); + + if (entropyBytes == null || entropyBytes.length != 32) { + LOGGER.info("Invalid entropy bytes"); + return false; + } + + if (this.currentWallet != null) { + if (this.currentWallet.entropyBytesEqual(entropyBytes)) { + // Wallet already active - nothing to do + return true; + } + else { + // Different wallet requested - close the existing one and switch over + this.closeCurrentWallet(); + } + } + + try { + this.currentWallet = new PirateWallet(entropyBytes, isNullSeedWallet); + if (!this.currentWallet.isReady()) { + // Don't persist wallets that aren't ready + this.currentWallet = null; + } + return true; + } catch (IOException e) { + LOGGER.info("Unable to initialize wallet: {}", e.getMessage()); + } + + return false; + } + + private void saveCurrentWallet() { + if (this.currentWallet == null) { + // Nothing to do + return; + } + try { + if (this.currentWallet.save()) { + Long now = NTP.getTime(); + if (now != null) { + this.lastSaveTime = now; + } + } + } catch (IOException e) { + LOGGER.info("Unable to save wallet"); + } + } + + public PirateWallet getCurrentWallet() { + return this.currentWallet; + } + + private void closeCurrentWallet() { + this.saveCurrentWallet(); + this.currentWallet = null; + } + + public void ensureInitialized() throws ForeignBlockchainException { + if (!LiteWalletJni.isLoaded() || this.currentWallet == null || !this.currentWallet.isInitialized()) { + throw new ForeignBlockchainException("Pirate wallet isn't initialized yet"); + } + } + + public void ensureNotNullSeed() throws ForeignBlockchainException { + // Safety check to make sure funds aren't sent to a null seed wallet + if (this.currentWallet == null || this.currentWallet.isNullSeedWallet()) { + throw new ForeignBlockchainException("Invalid wallet"); + } + } + + public void ensureSynchronized() throws ForeignBlockchainException { + if (this.currentWallet == null || !this.currentWallet.isSynchronized()) { + throw new ForeignBlockchainException("Wallet isn't synchronized yet"); + } + + String response = LiteWalletJni.execute("syncStatus", ""); + JSONObject json = new JSONObject(response); + if (json.has("syncing")) { + boolean isSyncing = Boolean.valueOf(json.getString("syncing")); + if (isSyncing) { + long syncedBlocks = json.getLong("synced_blocks"); + long totalBlocks = json.getLong("total_blocks"); + + throw new ForeignBlockchainException(String.format("Sync in progress (%d / %d). Please try again later.", syncedBlocks, totalBlocks)); + } + } + } + + public String getSyncStatus() { + if (this.currentWallet == null || !this.currentWallet.isInitialized()) { + if (this.loadStatus != null) { + return this.loadStatus; + } + + return "Not initialized yet"; + } + + String syncStatusResponse = LiteWalletJni.execute("syncStatus", ""); + org.json.JSONObject json = new JSONObject(syncStatusResponse); + if (json.has("syncing")) { + boolean isSyncing = Boolean.valueOf(json.getString("syncing")); + if (isSyncing) { + long syncedBlocks = json.getLong("synced_blocks"); + long totalBlocks = json.getLong("total_blocks"); + return String.format("Sync in progress (%d / %d)", syncedBlocks, totalBlocks); + } + } + + boolean isSynchronized = this.currentWallet.isSynchronized(); + if (isSynchronized) { + return "Synchronized"; + } + + return "Initializing wallet..."; + } + +} diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataFileListManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataFileListManager.java index 60b3707b..63a6df80 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataFileListManager.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataFileListManager.java @@ -123,12 +123,22 @@ public class ArbitraryDataFileListManager { } } - // Then allow another 5 attempts, each 5 minutes apart + // Then allow another 3 attempts, each 5 minutes apart if (timeSinceLastAttempt > 5 * 60 * 1000L) { // We haven't tried for at least 5 minutes - if (networkBroadcastCount < 5) { - // We've made less than 5 total attempts + if (networkBroadcastCount < 6) { + // We've made less than 6 total attempts + return true; + } + } + + // Then allow another 4 attempts, each 30 minutes apart + if (timeSinceLastAttempt > 30 * 60 * 1000L) { + // We haven't tried for at least 5 minutes + + if (networkBroadcastCount < 10) { + // We've made less than 10 total attempts return true; } } @@ -187,8 +197,8 @@ public class ArbitraryDataFileListManager { } } - if (timeSinceLastAttempt > 24 * 60 * 60 * 1000L) { - // We haven't tried for at least 24 hours + if (timeSinceLastAttempt > 60 * 60 * 1000L) { + // We haven't tried for at least 1 hour return true; } diff --git a/src/main/java/org/qortal/controller/tradebot/PirateChainACCTv3TradeBot.java b/src/main/java/org/qortal/controller/tradebot/PirateChainACCTv3TradeBot.java new file mode 100644 index 00000000..8f413093 --- /dev/null +++ b/src/main/java/org/qortal/controller/tradebot/PirateChainACCTv3TradeBot.java @@ -0,0 +1,913 @@ +package org.qortal.controller.tradebot; + +import com.google.common.hash.HashCode; +import com.rust.litewalletjni.LiteWalletJni; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bitcoinj.core.*; +import org.qortal.account.PrivateKeyAccount; +import org.qortal.account.PublicKeyAccount; +import org.qortal.api.model.crosschain.TradeBotCreateRequest; +import org.qortal.asset.Asset; +import org.qortal.crosschain.*; +import org.qortal.crypto.Crypto; +import org.qortal.data.at.ATData; +import org.qortal.data.crosschain.CrossChainTradeData; +import org.qortal.data.crosschain.TradeBotData; +import org.qortal.data.transaction.BaseTransactionData; +import org.qortal.data.transaction.DeployAtTransactionData; +import org.qortal.data.transaction.MessageTransactionData; +import org.qortal.group.Group; +import org.qortal.repository.DataException; +import org.qortal.repository.Repository; +import org.qortal.transaction.DeployAtTransaction; +import org.qortal.transaction.MessageTransaction; +import org.qortal.transaction.Transaction.ValidationResult; +import org.qortal.transform.TransformationException; +import org.qortal.transform.transaction.DeployAtTransactionTransformer; +import org.qortal.utils.Base58; +import org.qortal.utils.NTP; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static java.util.Arrays.stream; +import static java.util.stream.Collectors.toMap; + +/** + * Performing cross-chain trading steps on behalf of user. + *

+ * We deal with three different independent state-spaces here: + *

    + *
  • Qortal blockchain
  • + *
  • Foreign blockchain
  • + *
  • Trade-bot entries
  • + *
+ */ +public class PirateChainACCTv3TradeBot implements AcctTradeBot { + + private static final Logger LOGGER = LogManager.getLogger(PirateChainACCTv3TradeBot.class); + + public enum State implements TradeBot.StateNameAndValueSupplier { + BOB_WAITING_FOR_AT_CONFIRM(10, false, false), + BOB_WAITING_FOR_MESSAGE(15, true, true), + BOB_WAITING_FOR_AT_REDEEM(25, true, true), + BOB_DONE(30, false, false), + BOB_REFUNDED(35, false, false), + + ALICE_WAITING_FOR_AT_LOCK(85, true, true), + ALICE_DONE(95, false, false), + ALICE_REFUNDING_A(105, true, true), + ALICE_REFUNDED(110, false, false); + + private static final Map map = stream(State.values()).collect(toMap(state -> state.value, state -> state)); + + public final int value; + public final boolean requiresAtData; + public final boolean requiresTradeData; + + State(int value, boolean requiresAtData, boolean requiresTradeData) { + this.value = value; + this.requiresAtData = requiresAtData; + this.requiresTradeData = requiresTradeData; + } + + public static State valueOf(int value) { + return map.get(value); + } + + @Override + public String getState() { + return this.name(); + } + + @Override + public int getStateValue() { + return this.value; + } + } + + /** Maximum time Bob waits for his AT creation transaction to be confirmed into a block. (milliseconds) */ + private static final long MAX_AT_CONFIRMATION_PERIOD = 24 * 60 * 60 * 1000L; // ms + + private static PirateChainACCTv3TradeBot instance; + + private final List endStates = Arrays.asList(State.BOB_DONE, State.BOB_REFUNDED, State.ALICE_DONE, State.ALICE_REFUNDING_A, State.ALICE_REFUNDED).stream() + .map(State::name) + .collect(Collectors.toUnmodifiableList()); + + private PirateChainACCTv3TradeBot() { + } + + public static synchronized PirateChainACCTv3TradeBot getInstance() { + if (instance == null) + instance = new PirateChainACCTv3TradeBot(); + + return instance; + } + + @Override + public List getEndStates() { + return this.endStates; + } + + /** + * Creates a new trade-bot entry from the "Bob" viewpoint, i.e. OFFERing QORT in exchange for ARRR. + *

+ * Generates: + *

    + *
  • new 'trade' private key
  • + *
+ * Derives: + *
    + *
  • 'native' (as in Qortal) public key, public key hash, address (starting with Q)
  • + *
  • 'foreign' (as in PirateChain) public key, public key hash
  • + *
+ * A Qortal AT is then constructed including the following as constants in the 'data segment': + *
    + *
  • 'native'/Qortal 'trade' address - used as a MESSAGE contact
  • + *
  • 'foreign'/PirateChain public key hash - used by Alice's P2SH scripts to allow redeem
  • + *
  • QORT amount on offer by Bob
  • + *
  • ARRR amount expected in return by Bob (from Alice)
  • + *
  • trading timeout, in case things go wrong and everyone needs to refund
  • + *
+ * Returns a DEPLOY_AT transaction that needs to be signed and broadcast to the Qortal network. + *

+ * Trade-bot will wait for Bob's AT to be deployed before taking next step. + *

+ * @param repository + * @param tradeBotCreateRequest + * @return raw, unsigned DEPLOY_AT transaction + * @throws DataException + */ + public byte[] createTrade(Repository repository, TradeBotCreateRequest tradeBotCreateRequest) throws DataException { + byte[] tradePrivateKey = TradeBot.generateTradePrivateKey(); + + byte[] tradeNativePublicKey = TradeBot.deriveTradeNativePublicKey(tradePrivateKey); + byte[] tradeNativePublicKeyHash = Crypto.hash160(tradeNativePublicKey); + String tradeNativeAddress = Crypto.toAddress(tradeNativePublicKey); + + byte[] tradeForeignPublicKey = TradeBot.deriveTradeForeignPublicKey(tradePrivateKey); + byte[] tradeForeignPublicKeyHash = Crypto.hash160(tradeForeignPublicKey); + + // ARRR wallet must be loaded before a trade can be created + // This is to stop trades from nodes on unsupported architectures (e.g. 32bit) + if (!LiteWalletJni.isLoaded()) { + throw new DataException("Pirate wallet not found. Check wallets screen for details."); + } + + if (!PirateChain.getInstance().isValidAddress(tradeBotCreateRequest.receivingAddress)) { + throw new DataException("Unsupported Pirate Chain receiving address: " + tradeBotCreateRequest.receivingAddress); + } + + Bech32.Bech32Data decodedReceivingAddress = Bech32.decode(tradeBotCreateRequest.receivingAddress); + byte[] pirateChainReceivingAccountInfo = decodedReceivingAddress.data; + + PublicKeyAccount creator = new PublicKeyAccount(repository, tradeBotCreateRequest.creatorPublicKey); + + // Deploy AT + long timestamp = NTP.getTime(); + byte[] reference = creator.getLastReference(); + long fee = 0L; + byte[] signature = null; + BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, Group.NO_GROUP, reference, creator.getPublicKey(), fee, signature); + + String name = "QORT/ARRR ACCT"; + String description = "QORT/ARRR cross-chain trade"; + String aTType = "ACCT"; + String tags = "ACCT QORT ARRR"; + byte[] creationBytes = PirateChainACCTv3.buildQortalAT(tradeNativeAddress, tradeForeignPublicKey, tradeBotCreateRequest.qortAmount, + tradeBotCreateRequest.foreignAmount, tradeBotCreateRequest.tradeTimeout); + long amount = tradeBotCreateRequest.fundingQortAmount; + + DeployAtTransactionData deployAtTransactionData = new DeployAtTransactionData(baseTransactionData, name, description, aTType, tags, creationBytes, amount, Asset.QORT); + + DeployAtTransaction deployAtTransaction = new DeployAtTransaction(repository, deployAtTransactionData); + fee = deployAtTransaction.calcRecommendedFee(); + deployAtTransactionData.setFee(fee); + + DeployAtTransaction.ensureATAddress(deployAtTransactionData); + String atAddress = deployAtTransactionData.getAtAddress(); + + TradeBotData tradeBotData = new TradeBotData(tradePrivateKey, PirateChainACCTv3.NAME, + State.BOB_WAITING_FOR_AT_CONFIRM.name(), State.BOB_WAITING_FOR_AT_CONFIRM.value, + creator.getAddress(), atAddress, timestamp, tradeBotCreateRequest.qortAmount, + tradeNativePublicKey, tradeNativePublicKeyHash, tradeNativeAddress, + null, null, + SupportedBlockchain.PIRATECHAIN.name(), + tradeForeignPublicKey, tradeForeignPublicKeyHash, + tradeBotCreateRequest.foreignAmount, null, null, null, pirateChainReceivingAccountInfo); + + TradeBot.updateTradeBotState(repository, tradeBotData, () -> String.format("Built AT %s. Waiting for deployment", atAddress)); + + // Attempt to backup the trade bot data + TradeBot.backupTradeBotData(repository, null); + + // Return to user for signing and broadcast as we don't have their Qortal private key + try { + return DeployAtTransactionTransformer.toBytes(deployAtTransactionData); + } catch (TransformationException e) { + throw new DataException("Failed to transform DEPLOY_AT transaction?", e); + } + } + + /** + * Creates a trade-bot entry from the 'Alice' viewpoint, i.e. matching ARRR to an existing offer. + *

+ * Requires a chosen trade offer from Bob, passed by crossChainTradeData + * and access to a PirateChain wallet via xprv58. + *

+ * The crossChainTradeData contains the current trade offer state + * as extracted from the AT's data segment. + *

+ * Access to a funded wallet is via a PirateChain BIP32 hierarchical deterministic key, + * passed via xprv58. + * This key will be stored in your node's database + * to allow trade-bot to create/fund the necessary P2SH transactions! + * However, due to the nature of BIP32 keys, it is possible to give the trade-bot + * only a subset of wallet access (see BIP32 for more details). + *

+ * As an example, the xprv58 can be extract from a legacy, password-less + * Electrum wallet by going to the console tab and entering:
+ * wallet.keystore.xprv
+ * which should result in a base58 string starting with either 'xprv' (for PirateChain main-net) + * or 'tprv' for (PirateChain test-net). + *

+ * It is envisaged that the value in xprv58 will actually come from a Qortal-UI-managed wallet. + *

+ * If sufficient funds are available, this method will actually fund the P2SH-A + * with the PirateChain amount expected by 'Bob'. + *

+ * If the PirateChain transaction is successfully broadcast to the network then + * we also send a MESSAGE to Bob's trade-bot to let them know. + *

+ * The trade-bot entry is saved to the repository and the cross-chain trading process commences. + *

+ * @param repository + * @param crossChainTradeData chosen trade OFFER that Alice wants to match + * @param seed58 funded wallet xprv in base58 + * @return true if P2SH-A funding transaction successfully broadcast to PirateChain network, false otherwise + * @throws DataException + */ + public ResponseResult startResponse(Repository repository, ATData atData, ACCT acct, CrossChainTradeData crossChainTradeData, String seed58, String receivingAddress) throws DataException { + byte[] tradePrivateKey = TradeBot.generateTradePrivateKey(); + byte[] secretA = TradeBot.generateSecret(); + byte[] hashOfSecretA = Crypto.hash160(secretA); + + byte[] tradeNativePublicKey = TradeBot.deriveTradeNativePublicKey(tradePrivateKey); + byte[] tradeNativePublicKeyHash = Crypto.hash160(tradeNativePublicKey); + String tradeNativeAddress = Crypto.toAddress(tradeNativePublicKey); + + byte[] tradeForeignPublicKey = TradeBot.deriveTradeForeignPublicKey(tradePrivateKey); + byte[] tradeForeignPublicKeyHash = Crypto.hash160(tradeForeignPublicKey); + byte[] receivingPublicKeyHash = Base58.decode(receivingAddress); // Actually the whole address, not just PKH + + String tradePrivateKey58 = Base58.encode(tradePrivateKey); + String tradeForeignPublicKey58 = Base58.encode(tradeForeignPublicKey); + String secret58 = Base58.encode(secretA); + + // We need to generate lockTime-A: add tradeTimeout to now + long now = NTP.getTime(); + int lockTimeA = crossChainTradeData.tradeTimeout * 60 + (int) (now / 1000L); + + TradeBotData tradeBotData = new TradeBotData(tradePrivateKey, PirateChainACCTv3.NAME, + State.ALICE_WAITING_FOR_AT_LOCK.name(), State.ALICE_WAITING_FOR_AT_LOCK.value, + receivingAddress, crossChainTradeData.qortalAtAddress, now, crossChainTradeData.qortAmount, + tradeNativePublicKey, tradeNativePublicKeyHash, tradeNativeAddress, + secretA, hashOfSecretA, + SupportedBlockchain.PIRATECHAIN.name(), + tradeForeignPublicKey, tradeForeignPublicKeyHash, + crossChainTradeData.expectedForeignAmount, seed58, null, lockTimeA, receivingPublicKeyHash); + + // Attempt to backup the trade bot data + // Include tradeBotData as an additional parameter, since it's not in the repository yet + TradeBot.backupTradeBotData(repository, Arrays.asList(tradeBotData)); + + // Check we have enough funds via xprv58 to fund P2SH to cover expectedForeignAmount + long p2shFee; + try { + p2shFee = PirateChain.getInstance().getP2shFee(now); + } catch (ForeignBlockchainException e) { + LOGGER.debug("Couldn't estimate PirateChain fees?"); + return ResponseResult.NETWORK_ISSUE; + } + + // Fee for redeem/refund is subtracted from P2SH-A balance. + // Do not include fee for funding transaction as this is covered by buildSpend() + long amountA = crossChainTradeData.expectedForeignAmount + p2shFee /*redeeming/refunding P2SH-A*/; + + // P2SH-A to be funded + byte[] redeemScriptBytes = PirateChainHTLC.buildScript(tradeForeignPublicKey, lockTimeA, crossChainTradeData.creatorForeignPKH, hashOfSecretA); + String p2shAddressT3 = PirateChain.getInstance().deriveP2shAddress(redeemScriptBytes); // Use t3 prefix when funding + byte[] redeemScriptWithPrefixBytes = PirateChainHTLC.buildScriptWithPrefix(tradeForeignPublicKey, lockTimeA, crossChainTradeData.creatorForeignPKH, hashOfSecretA); + String redeemScriptWithPrefix58 = Base58.encode(redeemScriptWithPrefixBytes); + + // Send to P2SH address + try { + String txid = PirateChain.getInstance().fundP2SH(seed58, p2shAddressT3, amountA, redeemScriptWithPrefix58); + LOGGER.info("fundingTxidHex: {}", txid); + + } catch (ForeignBlockchainException e) { + LOGGER.debug("Unable to build and send P2SH-A funding transaction - lack of funds?"); + return ResponseResult.BALANCE_ISSUE; + } + + // Attempt to send MESSAGE to Bob's Qortal trade address + byte[] messageData = PirateChainACCTv3.buildOfferMessage(tradeBotData.getTradeForeignPublicKey(), tradeBotData.getHashOfSecret(), tradeBotData.getLockTimeA()); + String messageRecipient = crossChainTradeData.qortalCreatorTradeAddress; + + boolean isMessageAlreadySent = repository.getMessageRepository().exists(tradeBotData.getTradeNativePublicKey(), messageRecipient, messageData); + if (!isMessageAlreadySent) { + PrivateKeyAccount sender = new PrivateKeyAccount(repository, tradeBotData.getTradePrivateKey()); + MessageTransaction messageTransaction = MessageTransaction.build(repository, sender, Group.NO_GROUP, messageRecipient, messageData, false, false); + + messageTransaction.computeNonce(); + messageTransaction.sign(sender); + + // reset repository state to prevent deadlock + repository.discardChanges(); + ValidationResult result = messageTransaction.importAsUnconfirmed(); + + if (result != ValidationResult.OK) { + LOGGER.warn(() -> String.format("Unable to send MESSAGE to Bob's trade-bot %s: %s", messageRecipient, result.name())); + return ResponseResult.NETWORK_ISSUE; + } + } + + TradeBot.updateTradeBotState(repository, tradeBotData, () -> String.format("Funding P2SH-A %s. Messaged Bob. Waiting for AT-lock", p2shAddressT3)); + + return ResponseResult.OK; + } + + public static String hex(byte[] bytes) { + StringBuilder result = new StringBuilder(); + for (byte aByte : bytes) { + result.append(String.format("%02x", aByte)); + // upper case + // result.append(String.format("%02X", aByte)); + } + return result.toString(); + } + + @Override + public boolean canDelete(Repository repository, TradeBotData tradeBotData) throws DataException { + State tradeBotState = State.valueOf(tradeBotData.getStateValue()); + if (tradeBotState == null) + return true; + + // If the AT doesn't exist then we might as well let the user tidy up + if (!repository.getATRepository().exists(tradeBotData.getAtAddress())) + return true; + + switch (tradeBotState) { + case BOB_WAITING_FOR_AT_CONFIRM: + case ALICE_DONE: + case BOB_DONE: + case ALICE_REFUNDED: + case BOB_REFUNDED: + case ALICE_REFUNDING_A: + return true; + + default: + return false; + } + } + + @Override + public void progress(Repository repository, TradeBotData tradeBotData) throws DataException, ForeignBlockchainException { + State tradeBotState = State.valueOf(tradeBotData.getStateValue()); + if (tradeBotState == null) { + LOGGER.info(() -> String.format("Trade-bot entry for AT %s has invalid state?", tradeBotData.getAtAddress())); + return; + } + + ATData atData = null; + CrossChainTradeData tradeData = null; + + if (tradeBotState.requiresAtData) { + // Attempt to fetch AT data + atData = repository.getATRepository().fromATAddress(tradeBotData.getAtAddress()); + if (atData == null) { + LOGGER.debug(() -> String.format("Unable to fetch trade AT %s from repository", tradeBotData.getAtAddress())); + return; + } + + if (tradeBotState.requiresTradeData) { + tradeData = PirateChainACCTv3.getInstance().populateTradeData(repository, atData); + if (tradeData == null) { + LOGGER.warn(() -> String.format("Unable to fetch ACCT trade data for AT %s from repository", tradeBotData.getAtAddress())); + return; + } + } + } + + switch (tradeBotState) { + case BOB_WAITING_FOR_AT_CONFIRM: + handleBobWaitingForAtConfirm(repository, tradeBotData); + break; + + case BOB_WAITING_FOR_MESSAGE: + TradeBot.getInstance().updatePresence(repository, tradeBotData, tradeData); + handleBobWaitingForMessage(repository, tradeBotData, atData, tradeData); + break; + + case ALICE_WAITING_FOR_AT_LOCK: + TradeBot.getInstance().updatePresence(repository, tradeBotData, tradeData); + handleAliceWaitingForAtLock(repository, tradeBotData, atData, tradeData); + break; + + case BOB_WAITING_FOR_AT_REDEEM: + TradeBot.getInstance().updatePresence(repository, tradeBotData, tradeData); + handleBobWaitingForAtRedeem(repository, tradeBotData, atData, tradeData); + break; + + case ALICE_DONE: + case BOB_DONE: + break; + + case ALICE_REFUNDING_A: + TradeBot.getInstance().updatePresence(repository, tradeBotData, tradeData); + handleAliceRefundingP2shA(repository, tradeBotData, atData, tradeData); + break; + + case ALICE_REFUNDED: + case BOB_REFUNDED: + break; + } + } + + /** + * Trade-bot is waiting for Bob's AT to deploy. + *

+ * If AT is deployed, then trade-bot's next step is to wait for MESSAGE from Alice. + */ + private void handleBobWaitingForAtConfirm(Repository repository, TradeBotData tradeBotData) throws DataException { + if (!repository.getATRepository().exists(tradeBotData.getAtAddress())) { + if (NTP.getTime() - tradeBotData.getTimestamp() <= MAX_AT_CONFIRMATION_PERIOD) + return; + + // We've waited ages for AT to be confirmed into a block but something has gone awry. + // After this long we assume transaction loss so give up with trade-bot entry too. + tradeBotData.setState(State.BOB_REFUNDED.name()); + tradeBotData.setStateValue(State.BOB_REFUNDED.value); + tradeBotData.setTimestamp(NTP.getTime()); + // We delete trade-bot entry here instead of saving, hence not using updateTradeBotState() + repository.getCrossChainRepository().delete(tradeBotData.getTradePrivateKey()); + repository.saveChanges(); + + LOGGER.info(() -> String.format("AT %s never confirmed. Giving up on trade", tradeBotData.getAtAddress())); + TradeBot.notifyStateChange(tradeBotData); + return; + } + + TradeBot.updateTradeBotState(repository, tradeBotData, State.BOB_WAITING_FOR_MESSAGE, + () -> String.format("AT %s confirmed ready. Waiting for trade message", tradeBotData.getAtAddress())); + } + + /** + * Trade-bot is waiting for MESSAGE from Alice's trade-bot, containing Alice's trade info. + *

+ * It's possible Bob has cancelling his trade offer, receiving an automatic QORT refund, + * in which case trade-bot is done with this specific trade and finalizes on refunded state. + *

+ * Assuming trade is still on offer, trade-bot checks the contents of MESSAGE from Alice's trade-bot. + *

+ * Details from Alice are used to derive P2SH-A address and this is checked for funding balance. + *

+ * Assuming P2SH-A has at least expected PirateChain balance, + * Bob's trade-bot constructs a zero-fee, PoW MESSAGE to send to Bob's AT with more trade details. + *

+ * On processing this MESSAGE, Bob's AT should switch into 'TRADE' mode and only trade with Alice. + *

+ * Trade-bot's next step is to wait for Alice to redeem the AT, which will allow Bob to + * extract secret-A needed to redeem Alice's P2SH. + * @throws ForeignBlockchainException + */ + private void handleBobWaitingForMessage(Repository repository, TradeBotData tradeBotData, + ATData atData, CrossChainTradeData crossChainTradeData) throws DataException, ForeignBlockchainException { + // If AT has finished then Bob likely cancelled his trade offer + if (atData.getIsFinished()) { + TradeBot.updateTradeBotState(repository, tradeBotData, State.BOB_REFUNDED, + () -> String.format("AT %s cancelled - trading aborted", tradeBotData.getAtAddress())); + return; + } + + PirateChain pirateChain = PirateChain.getInstance(); + + String address = tradeBotData.getTradeNativeAddress(); + List messageTransactionsData = repository.getMessageRepository().getMessagesByParticipants(null, address, null, null, null); + + for (MessageTransactionData messageTransactionData : messageTransactionsData) { + if (messageTransactionData.isText()) + continue; + + // We're expecting: HASH160(secret-A), Alice's PirateChain pubkeyhash and lockTime-A + byte[] messageData = messageTransactionData.getData(); + PirateChainACCTv3.OfferMessageData offerMessageData = PirateChainACCTv3.extractOfferMessageData(messageData); + if (offerMessageData == null) + continue; + + byte[] aliceForeignPublicKey = offerMessageData.partnerPirateChainPublicKey; + byte[] hashOfSecretA = offerMessageData.hashOfSecretA; + int lockTimeA = (int) offerMessageData.lockTimeA; + long messageTimestamp = messageTransactionData.getTimestamp(); + int refundTimeout = PirateChainACCTv3.calcRefundTimeout(messageTimestamp, lockTimeA); + + // Determine P2SH-A address and confirm funded + byte[] redeemScriptA = PirateChainHTLC.buildScript(aliceForeignPublicKey, lockTimeA, tradeBotData.getTradeForeignPublicKey(), hashOfSecretA); + String p2shAddress = pirateChain.deriveP2shAddressBPrefix(redeemScriptA); // Use 'b' prefix when checking status + + long feeTimestamp = calcFeeTimestamp(lockTimeA, crossChainTradeData.tradeTimeout); + long p2shFee = PirateChain.getInstance().getP2shFee(feeTimestamp); + final long minimumAmountA = tradeBotData.getForeignAmount() + p2shFee; + + PirateChainHTLC.Status htlcStatusA = PirateChainHTLC.determineHtlcStatus(pirateChain.getBlockchainProvider(), p2shAddress, minimumAmountA); + + switch (htlcStatusA) { + case UNFUNDED: + case FUNDING_IN_PROGRESS: + // There might be another MESSAGE from someone else with an actually funded P2SH-A... + continue; + + case REDEEM_IN_PROGRESS: + case REDEEMED: + // We've already redeemed this? + TradeBot.updateTradeBotState(repository, tradeBotData, State.BOB_DONE, + () -> String.format("P2SH-A %s already spent? Assuming trade complete", p2shAddress)); + return; + + case REFUND_IN_PROGRESS: + case REFUNDED: + // This P2SH-A is burnt, but there might be another MESSAGE from someone else with an actually funded P2SH-A... + continue; + + case FUNDED: + // Fall-through out of switch... + break; + } + + // Good to go - send MESSAGE to AT + + String aliceNativeAddress = Crypto.toAddress(messageTransactionData.getCreatorPublicKey()); + + // Build outgoing message, padding each part to 32 bytes to make it easier for AT to consume + byte[] outgoingMessageData = PirateChainACCTv3.buildTradeMessage(aliceNativeAddress, aliceForeignPublicKey, hashOfSecretA, lockTimeA, refundTimeout); + String messageRecipient = tradeBotData.getAtAddress(); + + boolean isMessageAlreadySent = repository.getMessageRepository().exists(tradeBotData.getTradeNativePublicKey(), messageRecipient, outgoingMessageData); + if (!isMessageAlreadySent) { + PrivateKeyAccount sender = new PrivateKeyAccount(repository, tradeBotData.getTradePrivateKey()); + MessageTransaction outgoingMessageTransaction = MessageTransaction.build(repository, sender, Group.NO_GROUP, messageRecipient, outgoingMessageData, false, false); + + outgoingMessageTransaction.computeNonce(); + outgoingMessageTransaction.sign(sender); + + // reset repository state to prevent deadlock + repository.discardChanges(); + ValidationResult result = outgoingMessageTransaction.importAsUnconfirmed(); + + if (result != ValidationResult.OK) { + LOGGER.warn(() -> String.format("Unable to send MESSAGE to AT %s: %s", messageRecipient, result.name())); + return; + } + } + + TradeBot.updateTradeBotState(repository, tradeBotData, State.BOB_WAITING_FOR_AT_REDEEM, + () -> String.format("Locked AT %s to %s. Waiting for AT redeem", tradeBotData.getAtAddress(), aliceNativeAddress)); + + return; + } + } + + /** + * Trade-bot is waiting for Bob's AT to switch to TRADE mode and lock trade to Alice only. + *

+ * It's possible that Bob has cancelled his trade offer in the mean time, or that somehow + * this process has taken so long that we've reached P2SH-A's locktime, or that someone else + * has managed to trade with Bob. In any of these cases, trade-bot switches to begin the refunding process. + *

+ * Assuming Bob's AT is locked to Alice, trade-bot checks AT's state data to make sure it is correct. + *

+ * If all is well, trade-bot then redeems AT using Alice's secret-A, releasing Bob's QORT to Alice. + *

+ * In revealing a valid secret-A, Bob can then redeem the ARRR funds from P2SH-A. + *

+ * @throws ForeignBlockchainException + */ + private void handleAliceWaitingForAtLock(Repository repository, TradeBotData tradeBotData, + ATData atData, CrossChainTradeData crossChainTradeData) throws DataException, ForeignBlockchainException { + if (aliceUnexpectedState(repository, tradeBotData, atData, crossChainTradeData)) + return; + + PirateChain pirateChain = PirateChain.getInstance(); + int lockTimeA = tradeBotData.getLockTimeA(); + + // Refund P2SH-A if we've passed lockTime-A + if (NTP.getTime() >= lockTimeA * 1000L) { + byte[] redeemScriptA = PirateChainHTLC.buildScript(tradeBotData.getTradeForeignPublicKey(), lockTimeA, crossChainTradeData.creatorForeignPKH, tradeBotData.getHashOfSecret()); + String p2shAddress = pirateChain.deriveP2shAddressBPrefix(redeemScriptA); // Use 'b' prefix when checking status + + long feeTimestamp = calcFeeTimestamp(lockTimeA, crossChainTradeData.tradeTimeout); + long p2shFee = PirateChain.getInstance().getP2shFee(feeTimestamp); + long minimumAmountA = crossChainTradeData.expectedForeignAmount + p2shFee; + + PirateChainHTLC.Status htlcStatusA = PirateChainHTLC.determineHtlcStatus(pirateChain.getBlockchainProvider(), p2shAddress, minimumAmountA); + + switch (htlcStatusA) { + case UNFUNDED: + case FUNDING_IN_PROGRESS: + case FUNDED: + break; + + case REDEEM_IN_PROGRESS: + case REDEEMED: + // Already redeemed? + TradeBot.updateTradeBotState(repository, tradeBotData, State.ALICE_DONE, + () -> String.format("P2SH-A %s already spent? Assuming trade completed", p2shAddress)); + return; + + case REFUND_IN_PROGRESS: + case REFUNDED: + TradeBot.updateTradeBotState(repository, tradeBotData, State.ALICE_REFUNDED, + () -> String.format("P2SH-A %s already refunded. Trade aborted", p2shAddress)); + return; + + } + + TradeBot.updateTradeBotState(repository, tradeBotData, State.ALICE_REFUNDING_A, + () -> atData.getIsFinished() + ? String.format("AT %s cancelled. Refunding P2SH-A %s - aborting trade", tradeBotData.getAtAddress(), p2shAddress) + : String.format("LockTime-A reached, refunding P2SH-A %s - aborting trade", p2shAddress)); + + return; + } + + // We're waiting for AT to be in TRADE mode + if (crossChainTradeData.mode != AcctMode.TRADING) + return; + + // AT is in TRADE mode and locked to us as checked by aliceUnexpectedState() above + + // Find our MESSAGE to AT from previous state + List messageTransactionsData = repository.getMessageRepository().getMessagesByParticipants(tradeBotData.getTradeNativePublicKey(), + crossChainTradeData.qortalCreatorTradeAddress, null, null, null); + if (messageTransactionsData == null || messageTransactionsData.isEmpty()) { + LOGGER.warn(() -> String.format("Unable to find our message to trade creator %s?", crossChainTradeData.qortalCreatorTradeAddress)); + return; + } + + long recipientMessageTimestamp = messageTransactionsData.get(0).getTimestamp(); + int refundTimeout = PirateChainACCTv3.calcRefundTimeout(recipientMessageTimestamp, lockTimeA); + + // Our calculated refundTimeout should match AT's refundTimeout + if (refundTimeout != crossChainTradeData.refundTimeout) { + LOGGER.debug(() -> String.format("Trade AT refundTimeout '%d' doesn't match our refundTimeout '%d'", crossChainTradeData.refundTimeout, refundTimeout)); + // We'll eventually refund + return; + } + + // We're good to redeem AT + + // Send 'redeem' MESSAGE to AT using both secret + byte[] secretA = tradeBotData.getSecret(); + String qortalReceivingAddress = Base58.encode(tradeBotData.getReceivingAccountInfo()); // Actually contains whole address, not just PKH + byte[] messageData = PirateChainACCTv3.buildRedeemMessage(secretA, qortalReceivingAddress); + String messageRecipient = tradeBotData.getAtAddress(); + + boolean isMessageAlreadySent = repository.getMessageRepository().exists(tradeBotData.getTradeNativePublicKey(), messageRecipient, messageData); + if (!isMessageAlreadySent) { + PrivateKeyAccount sender = new PrivateKeyAccount(repository, tradeBotData.getTradePrivateKey()); + MessageTransaction messageTransaction = MessageTransaction.build(repository, sender, Group.NO_GROUP, messageRecipient, messageData, false, false); + + messageTransaction.computeNonce(); + messageTransaction.sign(sender); + + // Reset repository state to prevent deadlock + repository.discardChanges(); + ValidationResult result = messageTransaction.importAsUnconfirmed(); + + if (result != ValidationResult.OK) { + LOGGER.warn(() -> String.format("Unable to send MESSAGE to AT %s: %s", messageRecipient, result.name())); + return; + } + } + + TradeBot.updateTradeBotState(repository, tradeBotData, State.ALICE_DONE, + () -> String.format("Redeeming AT %s. Funds should arrive at %s", + tradeBotData.getAtAddress(), qortalReceivingAddress)); + } + + /** + * Trade-bot is waiting for Alice to redeem Bob's AT, thus revealing secret-A which is required to spend the ARRR funds from P2SH-A. + *

+ * It's possible that Bob's AT has reached its trading timeout and automatically refunded QORT back to Bob. In which case, + * trade-bot is done with this specific trade and finalizes in refunded state. + *

+ * Assuming trade-bot can extract a valid secret-A from Alice's MESSAGE then trade-bot uses that to redeem the ARRR funds from P2SH-A + * to Bob's 'foreign'/PirateChain trade legacy-format address, as derived from trade private key. + *

+ * (This could potentially be 'improved' to send ARRR to any address of Bob's choosing by changing the transaction output). + *

+ * If trade-bot successfully broadcasts the transaction, then this specific trade is done. + * @throws ForeignBlockchainException + */ + private void handleBobWaitingForAtRedeem(Repository repository, TradeBotData tradeBotData, + ATData atData, CrossChainTradeData crossChainTradeData) throws DataException, ForeignBlockchainException { + // AT should be 'finished' once Alice has redeemed QORT funds + if (!atData.getIsFinished()) + // Not finished yet + return; + + // If AT is REFUNDED or CANCELLED then something has gone wrong + if (crossChainTradeData.mode == AcctMode.REFUNDED || crossChainTradeData.mode == AcctMode.CANCELLED) { + // Alice hasn't redeemed the QORT, so there is no point in trying to redeem the ARRR + TradeBot.updateTradeBotState(repository, tradeBotData, State.BOB_REFUNDED, + () -> String.format("AT %s has auto-refunded - trade aborted", tradeBotData.getAtAddress())); + + return; + } + + byte[] secretA = PirateChainACCTv3.getInstance().findSecretA(repository, crossChainTradeData); + if (secretA == null) { + LOGGER.debug(() -> String.format("Unable to find secret-A from redeem message to AT %s?", tradeBotData.getAtAddress())); + return; + } + + // Use secret-A to redeem P2SH-A + + PirateChain pirateChain = PirateChain.getInstance(); + + byte[] receivingAccountInfo = tradeBotData.getReceivingAccountInfo(); + int lockTimeA = crossChainTradeData.lockTimeA; + byte[] redeemScriptA = PirateChainHTLC.buildScript(crossChainTradeData.partnerForeignPKH, lockTimeA, crossChainTradeData.creatorForeignPKH, crossChainTradeData.hashOfSecretA); + String p2shAddress = pirateChain.deriveP2shAddressBPrefix(redeemScriptA); // Use 'b' prefix when checking status + String p2shAddressT3 = pirateChain.deriveP2shAddress(redeemScriptA); // Use 't3' prefix when refunding + + // Fee for redeem/refund is subtracted from P2SH-A balance. + long feeTimestamp = calcFeeTimestamp(lockTimeA, crossChainTradeData.tradeTimeout); + long p2shFee = PirateChain.getInstance().getP2shFee(feeTimestamp); + long minimumAmountA = crossChainTradeData.expectedForeignAmount + p2shFee; + String receivingAddress = Bech32.encode("zs", receivingAccountInfo); + + PirateChainHTLC.Status htlcStatusA = PirateChainHTLC.determineHtlcStatus(pirateChain.getBlockchainProvider(), p2shAddress, minimumAmountA); + + switch (htlcStatusA) { + case UNFUNDED: + case FUNDING_IN_PROGRESS: + // P2SH-A suddenly not funded? Our best bet at this point is to hope for AT auto-refund + return; + + case REDEEM_IN_PROGRESS: + case REDEEMED: + // Double-check that we have redeemed P2SH-A... + break; + + case REFUND_IN_PROGRESS: + case REFUNDED: + // Wait for AT to auto-refund + return; + + case FUNDED: { + // Get funding txid + String fundingTxidHex = PirateChainHTLC.getUnspentFundingTxid(pirateChain.getBlockchainProvider(), p2shAddress, minimumAmountA); + if (fundingTxidHex == null) { + throw new ForeignBlockchainException("Missing funding txid when redeeming P2SH"); + } + String fundingTxid58 = Base58.encode(HashCode.fromString(fundingTxidHex).asBytes()); + + // Redeem P2SH + Coin redeemAmount = Coin.valueOf(crossChainTradeData.expectedForeignAmount); + byte[] privateKey = tradeBotData.getTradePrivateKey(); + String secret58 = Base58.encode(secretA); + String privateKey58 = Base58.encode(privateKey); + String redeemScript58 = Base58.encode(redeemScriptA); + + String txid = PirateChain.getInstance().redeemP2sh(p2shAddressT3, receivingAddress, redeemAmount.value, + redeemScript58, fundingTxid58, secret58, privateKey58); + LOGGER.info("Redeem txid: {}", txid); + break; + } + } + + TradeBot.updateTradeBotState(repository, tradeBotData, State.BOB_DONE, + () -> String.format("P2SH-A %s redeemed. Funds should arrive at %s", tradeBotData.getAtAddress(), receivingAddress)); + } + + /** + * Trade-bot is attempting to refund P2SH-A. + * @throws ForeignBlockchainException + */ + private void handleAliceRefundingP2shA(Repository repository, TradeBotData tradeBotData, + ATData atData, CrossChainTradeData crossChainTradeData) throws DataException, ForeignBlockchainException { + int lockTimeA = tradeBotData.getLockTimeA(); + + // We can't refund P2SH-A until lockTime-A has passed + if (NTP.getTime() <= lockTimeA * 1000L) + return; + + PirateChain pirateChain = PirateChain.getInstance(); + + // We can't refund P2SH-A until median block time has passed lockTime-A (see BIP113) + int medianBlockTime = pirateChain.getMedianBlockTime(); + if (medianBlockTime <= lockTimeA) + return; + + byte[] redeemScriptA = PirateChainHTLC.buildScript(tradeBotData.getTradeForeignPublicKey(), lockTimeA, crossChainTradeData.creatorForeignPKH, tradeBotData.getHashOfSecret()); + String p2shAddress = pirateChain.deriveP2shAddressBPrefix(redeemScriptA); // Use 'b' prefix when checking status + String p2shAddressT3 = pirateChain.deriveP2shAddress(redeemScriptA); // Use 't3' prefix when refunding + + // Fee for redeem/refund is subtracted from P2SH-A balance. + long feeTimestamp = calcFeeTimestamp(lockTimeA, crossChainTradeData.tradeTimeout); + long p2shFee = PirateChain.getInstance().getP2shFee(feeTimestamp); + long minimumAmountA = crossChainTradeData.expectedForeignAmount + p2shFee; + PirateChainHTLC.Status htlcStatusA = PirateChainHTLC.determineHtlcStatus(pirateChain.getBlockchainProvider(), p2shAddress, minimumAmountA); + + switch (htlcStatusA) { + case UNFUNDED: + case FUNDING_IN_PROGRESS: + // Still waiting for P2SH-A to be funded... + return; + + case REDEEM_IN_PROGRESS: + case REDEEMED: + // Too late! + TradeBot.updateTradeBotState(repository, tradeBotData, State.ALICE_DONE, + () -> String.format("P2SH-A %s already spent!", p2shAddress)); + return; + + case REFUND_IN_PROGRESS: + case REFUNDED: + break; + + case FUNDED:{ + // Get funding txid + String fundingTxidHex = PirateChainHTLC.getUnspentFundingTxid(pirateChain.getBlockchainProvider(), p2shAddress, minimumAmountA); + if (fundingTxidHex == null) { + throw new ForeignBlockchainException("Missing funding txid when refunding P2SH"); + } + String fundingTxid58 = Base58.encode(HashCode.fromString(fundingTxidHex).asBytes()); + + Coin refundAmount = Coin.valueOf(crossChainTradeData.expectedForeignAmount); + byte[] privateKey = tradeBotData.getTradePrivateKey(); + String privateKey58 = Base58.encode(privateKey); + String redeemScript58 = Base58.encode(redeemScriptA); + String receivingAddress = pirateChain.getWalletAddress(tradeBotData.getForeignKey()); + + String txid = PirateChain.getInstance().refundP2sh(p2shAddressT3, + receivingAddress, refundAmount.value, redeemScript58, fundingTxid58, lockTimeA, privateKey58); + LOGGER.info("Refund txid: {}", txid); + break; + } + } + + TradeBot.updateTradeBotState(repository, tradeBotData, State.ALICE_REFUNDED, + () -> String.format("LockTime-A reached. Refunded P2SH-A %s. Trade aborted", p2shAddress)); + } + + /** + * Returns true if Alice finds AT unexpectedly cancelled, refunded, redeemed or locked to someone else. + *

+ * Will automatically update trade-bot state to ALICE_REFUNDING_A or ALICE_DONE as necessary. + * + * @throws DataException + * @throws ForeignBlockchainException + */ + private boolean aliceUnexpectedState(Repository repository, TradeBotData tradeBotData, + ATData atData, CrossChainTradeData crossChainTradeData) throws DataException, ForeignBlockchainException { + // This is OK + if (!atData.getIsFinished() && crossChainTradeData.mode == AcctMode.OFFERING) + return false; + + boolean isAtLockedToUs = tradeBotData.getTradeNativeAddress().equals(crossChainTradeData.qortalPartnerAddress); + + if (!atData.getIsFinished() && crossChainTradeData.mode == AcctMode.TRADING) + if (isAtLockedToUs) { + // AT is trading with us - OK + return false; + } else { + TradeBot.updateTradeBotState(repository, tradeBotData, State.ALICE_REFUNDING_A, + () -> String.format("AT %s trading with someone else: %s. Refunding & aborting trade", tradeBotData.getAtAddress(), crossChainTradeData.qortalPartnerAddress)); + + return true; + } + + if (atData.getIsFinished() && crossChainTradeData.mode == AcctMode.REDEEMED && isAtLockedToUs) { + // We've redeemed already? + TradeBot.updateTradeBotState(repository, tradeBotData, State.ALICE_DONE, + () -> String.format("AT %s already redeemed by us. Trade completed", tradeBotData.getAtAddress())); + } else { + // Any other state is not good, so start defensive refund + TradeBot.updateTradeBotState(repository, tradeBotData, State.ALICE_REFUNDING_A, + () -> String.format("AT %s cancelled/refunded/redeemed by someone else/invalid state. Refunding & aborting trade", tradeBotData.getAtAddress())); + } + + return true; + } + + private long calcFeeTimestamp(int lockTimeA, int tradeTimeout) { + return (lockTimeA - tradeTimeout * 60) * 1000L; + } + +} diff --git a/src/main/java/org/qortal/controller/tradebot/TradeBot.java b/src/main/java/org/qortal/controller/tradebot/TradeBot.java index 2c448607..05ba8f1b 100644 --- a/src/main/java/org/qortal/controller/tradebot/TradeBot.java +++ b/src/main/java/org/qortal/controller/tradebot/TradeBot.java @@ -103,6 +103,7 @@ public class TradeBot implements Listener { acctTradeBotSuppliers.put(DogecoinACCTv3.class, DogecoinACCTv3TradeBot::getInstance); acctTradeBotSuppliers.put(DigibyteACCTv3.class, DigibyteACCTv3TradeBot::getInstance); acctTradeBotSuppliers.put(RavencoinACCTv3.class, RavencoinACCTv3TradeBot::getInstance); + acctTradeBotSuppliers.put(PirateChainACCTv3.class, PirateChainACCTv3TradeBot::getInstance); } private static TradeBot instance; @@ -299,7 +300,7 @@ public class TradeBot implements Listener { return ECKey.fromPrivate(privateKey).getPubKey(); } - /*package*/ static byte[] generateSecret() { + /*package*/ public static byte[] generateSecret() { byte[] secret = new byte[32]; RANDOM.nextBytes(secret); return secret; diff --git a/src/main/java/org/qortal/crosschain/Bitcoin.java b/src/main/java/org/qortal/crosschain/Bitcoin.java index afd42590..7fec5a17 100644 --- a/src/main/java/org/qortal/crosschain/Bitcoin.java +++ b/src/main/java/org/qortal/crosschain/Bitcoin.java @@ -174,6 +174,8 @@ public class Bitcoin extends Bitcoiny { Context bitcoinjContext = new Context(bitcoinNet.getParams()); instance = new Bitcoin(bitcoinNet, electrumX, bitcoinjContext, CURRENCY_CODE); + + electrumX.setBlockchain(instance); } return instance; diff --git a/src/main/java/org/qortal/crosschain/Bitcoiny.java b/src/main/java/org/qortal/crosschain/Bitcoiny.java index 56c5b409..350779bc 100644 --- a/src/main/java/org/qortal/crosschain/Bitcoiny.java +++ b/src/main/java/org/qortal/crosschain/Bitcoiny.java @@ -29,6 +29,7 @@ import org.bitcoinj.wallet.SendRequest; import org.bitcoinj.wallet.Wallet; import org.qortal.api.model.SimpleForeignTransaction; import org.qortal.crypto.Crypto; +import org.qortal.settings.Settings; import org.qortal.utils.Amounts; import org.qortal.utils.BitTwiddling; @@ -42,7 +43,7 @@ public abstract class Bitcoiny implements ForeignBlockchain { public static final int HASH160_LENGTH = 20; - protected final BitcoinyBlockchainProvider blockchain; + protected final BitcoinyBlockchainProvider blockchainProvider; protected final Context bitcoinjContext; protected final String currencyCode; @@ -61,18 +62,13 @@ public abstract class Bitcoiny implements ForeignBlockchain { /** How many wallet keys to generate in each batch. */ private static final int WALLET_KEY_LOOKAHEAD_INCREMENT = 3; - /** How many wallet keys to generate when using bitcoinj as the data provider. - * We must use a higher value here since we are unable to request multiple batches of keys. - * Without this, the bitcoinj state can be missing transactions, causing errors such as "insufficient balance". */ - private static final int WALLET_KEY_LOOKAHEAD_INCREMENT_BITCOINJ = 50; - /** Byte offset into raw block headers to block timestamp. */ private static final int TIMESTAMP_OFFSET = 4 + 32 + 32; // Constructors and instance - protected Bitcoiny(BitcoinyBlockchainProvider blockchain, Context bitcoinjContext, String currencyCode) { - this.blockchain = blockchain; + protected Bitcoiny(BitcoinyBlockchainProvider blockchainProvider, Context bitcoinjContext, String currencyCode) { + this.blockchainProvider = blockchainProvider; this.bitcoinjContext = bitcoinjContext; this.currencyCode = currencyCode; @@ -82,7 +78,7 @@ public abstract class Bitcoiny implements ForeignBlockchain { // Getters & setters public BitcoinyBlockchainProvider getBlockchainProvider() { - return this.blockchain; + return this.blockchainProvider; } public Context getBitcoinjContext() { @@ -155,10 +151,10 @@ public abstract class Bitcoiny implements ForeignBlockchain { * @throws ForeignBlockchainException if error occurs */ public int getMedianBlockTime() throws ForeignBlockchainException { - int height = this.blockchain.getCurrentHeight(); + int height = this.blockchainProvider.getCurrentHeight(); // Grab latest 11 blocks - List blockHeaders = this.blockchain.getRawBlockHeaders(height - 11, 11); + List blockHeaders = this.blockchainProvider.getRawBlockHeaders(height - 11, 11); if (blockHeaders.size() < 11) throw new ForeignBlockchainException("Not enough blocks to determine median block time"); @@ -197,7 +193,7 @@ public abstract class Bitcoiny implements ForeignBlockchain { * @throws ForeignBlockchainException if there was an error */ public long getConfirmedBalance(String base58Address) throws ForeignBlockchainException { - return this.blockchain.getConfirmedBalance(addressToScriptPubKey(base58Address)); + return this.blockchainProvider.getConfirmedBalance(addressToScriptPubKey(base58Address)); } /** @@ -208,7 +204,7 @@ public abstract class Bitcoiny implements ForeignBlockchain { */ // TODO: don't return bitcoinj-based objects like TransactionOutput, use BitcoinyTransaction.Output instead public List getUnspentOutputs(String base58Address) throws ForeignBlockchainException { - List unspentOutputs = this.blockchain.getUnspentOutputs(addressToScriptPubKey(base58Address), false); + List unspentOutputs = this.blockchainProvider.getUnspentOutputs(addressToScriptPubKey(base58Address), false); List unspentTransactionOutputs = new ArrayList<>(); for (UnspentOutput unspentOutput : unspentOutputs) { @@ -228,7 +224,7 @@ public abstract class Bitcoiny implements ForeignBlockchain { */ // TODO: don't return bitcoinj-based objects like TransactionOutput, use BitcoinyTransaction.Output instead public List getOutputs(byte[] txHash) throws ForeignBlockchainException { - byte[] rawTransactionBytes = this.blockchain.getRawTransaction(txHash); + byte[] rawTransactionBytes = this.blockchainProvider.getRawTransaction(txHash); Context.propagate(bitcoinjContext); Transaction transaction = new Transaction(this.params, rawTransactionBytes); @@ -245,7 +241,7 @@ public abstract class Bitcoiny implements ForeignBlockchain { ForeignBlockchainException e2 = null; while (retries <= 3) { try { - return this.blockchain.getAddressTransactions(scriptPubKey, includeUnconfirmed); + return this.blockchainProvider.getAddressTransactions(scriptPubKey, includeUnconfirmed); } catch (ForeignBlockchainException e) { e2 = e; retries++; @@ -261,7 +257,7 @@ public abstract class Bitcoiny implements ForeignBlockchain { * @throws ForeignBlockchainException if there was an error. */ public List getAddressTransactions(String base58Address, boolean includeUnconfirmed) throws ForeignBlockchainException { - return this.blockchain.getAddressTransactions(addressToScriptPubKey(base58Address), includeUnconfirmed); + return this.blockchainProvider.getAddressTransactions(addressToScriptPubKey(base58Address), includeUnconfirmed); } /** @@ -270,11 +266,11 @@ public abstract class Bitcoiny implements ForeignBlockchain { * @throws ForeignBlockchainException if there was an error */ public List getAddressTransactions(String base58Address) throws ForeignBlockchainException { - List transactionHashes = this.blockchain.getAddressTransactions(addressToScriptPubKey(base58Address), false); + List transactionHashes = this.blockchainProvider.getAddressTransactions(addressToScriptPubKey(base58Address), false); List rawTransactions = new ArrayList<>(); for (TransactionHash transactionInfo : transactionHashes) { - byte[] rawTransaction = this.blockchain.getRawTransaction(HashCode.fromString(transactionInfo.txHash).asBytes()); + byte[] rawTransaction = this.blockchainProvider.getRawTransaction(HashCode.fromString(transactionInfo.txHash).asBytes()); rawTransactions.add(rawTransaction); } @@ -292,7 +288,7 @@ public abstract class Bitcoiny implements ForeignBlockchain { ForeignBlockchainException e2 = null; while (retries <= 3) { try { - return this.blockchain.getTransaction(txHash); + return this.blockchainProvider.getTransaction(txHash); } catch (ForeignBlockchainException e) { e2 = e; retries++; @@ -307,7 +303,7 @@ public abstract class Bitcoiny implements ForeignBlockchain { * @throws ForeignBlockchainException if error occurs */ public void broadcastTransaction(Transaction transaction) throws ForeignBlockchainException { - this.blockchain.broadcastTransaction(transaction.bitcoinSerialize()); + this.blockchainProvider.broadcastTransaction(transaction.bitcoinSerialize()); } /** @@ -360,17 +356,20 @@ public abstract class Bitcoiny implements ForeignBlockchain { * @param key58 BIP32/HD extended Bitcoin private/public key * @return unspent BTC balance, or null if unable to determine balance */ - public Long getWalletBalance(String key58) { - Context.propagate(bitcoinjContext); + public Long getWalletBalance(String key58) throws ForeignBlockchainException { + // It's more accurate to calculate the balance from the transactions, rather than asking Bitcoinj + return this.getWalletBalanceFromTransactions(key58); - Wallet wallet = walletFromDeterministicKey58(key58); - wallet.setUTXOProvider(new WalletAwareUTXOProvider(this, wallet)); - - Coin balance = wallet.getBalance(); - if (balance == null) - return null; - - return balance.value; +// Context.propagate(bitcoinjContext); +// +// Wallet wallet = walletFromDeterministicKey58(key58); +// wallet.setUTXOProvider(new WalletAwareUTXOProvider(this, wallet)); +// +// Coin balance = wallet.getBalance(); +// if (balance == null) +// return null; +// +// return balance.value; } public Long getWalletBalanceFromTransactions(String key58) throws ForeignBlockchainException { @@ -409,9 +408,6 @@ public abstract class Bitcoiny implements ForeignBlockchain { Set walletTransactions = new HashSet<>(); Set keySet = new HashSet<>(); - // Set the number of consecutive empty batches required before giving up - final int numberOfAdditionalBatchesToSearch = 7; - int unusedCounter = 0; int ki = 0; do { @@ -438,12 +434,12 @@ public abstract class Bitcoiny implements ForeignBlockchain { if (areAllKeysUnused) { // No transactions - if (unusedCounter >= numberOfAdditionalBatchesToSearch) { + if (unusedCounter >= Settings.getInstance().getGapLimit()) { // ... and we've hit our search limit break; } // We haven't hit our search limit yet so increment the counter and keep looking - unusedCounter++; + unusedCounter += WALLET_KEY_LOOKAHEAD_INCREMENT; } else { // Some keys in this batch were used, so reset the counter unusedCounter = 0; @@ -538,7 +534,7 @@ public abstract class Bitcoiny implements ForeignBlockchain { amount = 0; } long timestampMillis = t.timestamp * 1000L; - return new SimpleTransaction(t.txHash, timestampMillis, amount, fee, inputs, outputs); + return new SimpleTransaction(t.txHash, timestampMillis, amount, fee, inputs, outputs, null); } /** @@ -574,7 +570,7 @@ public abstract class Bitcoiny implements ForeignBlockchain { Address address = Address.fromKey(this.params, dKey, ScriptType.P2PKH); byte[] script = ScriptBuilder.createOutputScript(address).getProgram(); - List unspentOutputs = this.blockchain.getUnspentOutputs(script, false); + List unspentOutputs = this.blockchainProvider.getUnspentOutputs(script, false); /* * If there are no unspent outputs then either: @@ -592,7 +588,7 @@ public abstract class Bitcoiny implements ForeignBlockchain { } // Ask for transaction history - if it's empty then key has never been used - List historicTransactionHashes = this.blockchain.getAddressTransactions(script, false); + List historicTransactionHashes = this.blockchainProvider.getAddressTransactions(script, false); if (!historicTransactionHashes.isEmpty()) { // Fully spent key - case (a) @@ -630,7 +626,7 @@ public abstract class Bitcoiny implements ForeignBlockchain { this.keyChain = this.wallet.getActiveKeyChain(); // Set up wallet's key chain - this.keyChain.setLookaheadSize(Bitcoiny.WALLET_KEY_LOOKAHEAD_INCREMENT_BITCOINJ); + this.keyChain.setLookaheadSize(Settings.getInstance().getBitcoinjLookaheadSize()); this.keyChain.maybeLookAhead(); } @@ -651,7 +647,7 @@ public abstract class Bitcoiny implements ForeignBlockchain { List unspentOutputs; try { - unspentOutputs = this.bitcoiny.blockchain.getUnspentOutputs(script, false); + unspentOutputs = this.bitcoiny.blockchainProvider.getUnspentOutputs(script, false); } catch (ForeignBlockchainException e) { throw new UTXOProviderException(String.format("Unable to fetch unspent outputs for %s", address)); } @@ -675,7 +671,7 @@ public abstract class Bitcoiny implements ForeignBlockchain { // Ask for transaction history - if it's empty then key has never been used List historicTransactionHashes; try { - historicTransactionHashes = this.bitcoiny.blockchain.getAddressTransactions(script, false); + historicTransactionHashes = this.bitcoiny.blockchainProvider.getAddressTransactions(script, false); } catch (ForeignBlockchainException e) { throw new UTXOProviderException(String.format("Unable to fetch transaction history for %s", address)); } @@ -728,7 +724,7 @@ public abstract class Bitcoiny implements ForeignBlockchain { @Override public int getChainHeadHeight() throws UTXOProviderException { try { - return this.bitcoiny.blockchain.getCurrentHeight(); + return this.bitcoiny.blockchainProvider.getCurrentHeight(); } catch (ForeignBlockchainException e) { throw new UTXOProviderException("Unable to determine Bitcoiny chain height"); } diff --git a/src/main/java/org/qortal/crosschain/BitcoinyBlockchainProvider.java b/src/main/java/org/qortal/crosschain/BitcoinyBlockchainProvider.java index 7691efb1..8075bfff 100644 --- a/src/main/java/org/qortal/crosschain/BitcoinyBlockchainProvider.java +++ b/src/main/java/org/qortal/crosschain/BitcoinyBlockchainProvider.java @@ -1,5 +1,7 @@ package org.qortal.crosschain; +import cash.z.wallet.sdk.rpc.CompactFormats.*; + import java.util.List; public abstract class BitcoinyBlockchainProvider { @@ -7,18 +9,32 @@ public abstract class BitcoinyBlockchainProvider { public static final boolean INCLUDE_UNCONFIRMED = true; public static final boolean EXCLUDE_UNCONFIRMED = false; + /** Sets the blockchain using this provider instance */ + public abstract void setBlockchain(Bitcoiny blockchain); + /** Returns ID unique to bitcoiny network (e.g. "Litecoin-TEST3") */ public abstract String getNetId(); /** Returns current blockchain height. */ public abstract int getCurrentHeight() throws ForeignBlockchainException; + /** Returns a list of compact blocks, starting at startHeight (inclusive), up to count max. + * Used for Pirate/Zcash only. If ever needed for other blockchains, the response format will need to be + * made generic. */ + public abstract List getCompactBlocks(int startHeight, int count) throws ForeignBlockchainException; + /** Returns a list of raw block headers, starting at startHeight (inclusive), up to count max. */ public abstract List getRawBlockHeaders(int startHeight, int count) throws ForeignBlockchainException; + /** Returns a list of block timestamps, starting at startHeight (inclusive), up to count max. */ + public abstract List getBlockTimestamps(int startHeight, int count) throws ForeignBlockchainException; + /** Returns balance of address represented by scriptPubKey. */ public abstract long getConfirmedBalance(byte[] scriptPubKey) throws ForeignBlockchainException; + /** Returns balance of base58 encoded address. */ + public abstract long getConfirmedAddressBalance(String base58Address) throws ForeignBlockchainException; + /** Returns raw, serialized, transaction bytes given txHash. */ public abstract byte[] getRawTransaction(String txHash) throws ForeignBlockchainException; @@ -31,6 +47,12 @@ public abstract class BitcoinyBlockchainProvider { /** Returns list of transaction hashes (and heights) for address represented by scriptPubKey, optionally including unconfirmed transactions. */ public abstract List getAddressTransactions(byte[] scriptPubKey, boolean includeUnconfirmed) throws ForeignBlockchainException; + /** Returns list of BitcoinyTransaction objects for address, optionally including unconfirmed transactions. */ + public abstract List getAddressBitcoinyTransactions(String address, boolean includeUnconfirmed) throws ForeignBlockchainException; + + /** Returns list of unspent transaction outputs for address, optionally including unconfirmed transactions. */ + public abstract List getUnspentOutputs(String address, boolean includeUnconfirmed) throws ForeignBlockchainException; + /** Returns list of unspent transaction outputs for address represented by scriptPubKey, optionally including unconfirmed transactions. */ public abstract List getUnspentOutputs(byte[] scriptPubKey, boolean includeUnconfirmed) throws ForeignBlockchainException; diff --git a/src/main/java/org/qortal/crosschain/BitcoinyTransaction.java b/src/main/java/org/qortal/crosschain/BitcoinyTransaction.java index caf0b36d..90ee2b23 100644 --- a/src/main/java/org/qortal/crosschain/BitcoinyTransaction.java +++ b/src/main/java/org/qortal/crosschain/BitcoinyTransaction.java @@ -1,5 +1,6 @@ package org.qortal.crosschain; +import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; @@ -10,8 +11,13 @@ import javax.xml.bind.annotation.XmlTransient; @XmlAccessorType(XmlAccessType.FIELD) public class BitcoinyTransaction { + public static final Comparator CONFIRMED_FIRST = (a, b) -> Boolean.compare(a.height != 0, b.height != 0); + public final String txHash; + @XmlTransient + public Integer height; + @XmlTransient public final int size; @@ -113,6 +119,10 @@ public class BitcoinyTransaction { this.totalAmount = outputs.stream().map(output -> output.value).reduce(0L, Long::sum); } + public int getHeight() { + return this.height; + } + public String toString() { return String.format("txHash %s, size %d, locktime %d, timestamp %d\n" + "\tinputs: [%s]\n" diff --git a/src/main/java/org/qortal/crosschain/Dogecoin.java b/src/main/java/org/qortal/crosschain/Dogecoin.java index 219c762c..d6955e18 100644 --- a/src/main/java/org/qortal/crosschain/Dogecoin.java +++ b/src/main/java/org/qortal/crosschain/Dogecoin.java @@ -135,6 +135,8 @@ public class Dogecoin extends Bitcoiny { Context bitcoinjContext = new Context(dogecoinNet.getParams()); instance = new Dogecoin(dogecoinNet, electrumX, bitcoinjContext, CURRENCY_CODE); + + electrumX.setBlockchain(instance); } return instance; diff --git a/src/main/java/org/qortal/crosschain/ElectrumX.java b/src/main/java/org/qortal/crosschain/ElectrumX.java index 6d6cfb15..a2a42089 100644 --- a/src/main/java/org/qortal/crosschain/ElectrumX.java +++ b/src/main/java/org/qortal/crosschain/ElectrumX.java @@ -11,6 +11,7 @@ import java.util.regex.Pattern; import javax.net.ssl.SSLSocketFactory; +import cash.z.wallet.sdk.rpc.CompactFormats.*; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.json.simple.JSONArray; @@ -107,6 +108,7 @@ public class ElectrumX extends BitcoinyBlockchainProvider { private final String netId; private final String expectedGenesisHash; private final Map defaultPorts = new EnumMap<>(Server.ConnectionType.class); + private Bitcoiny blockchain; private final Object serverLock = new Object(); private Server currentServer; @@ -135,6 +137,11 @@ public class ElectrumX extends BitcoinyBlockchainProvider { // Methods for use by other classes + @Override + public void setBlockchain(Bitcoiny blockchain) { + this.blockchain = blockchain; + } + @Override public String getNetId() { return this.netId; @@ -161,6 +168,16 @@ public class ElectrumX extends BitcoinyBlockchainProvider { return ((Long) heightObj).intValue(); } + /** + * Returns list of raw blocks, starting from startHeight inclusive. + *

+ * @throws ForeignBlockchainException if error occurs + */ + @Override + public List getCompactBlocks(int startHeight, int count) throws ForeignBlockchainException { + throw new ForeignBlockchainException("getCompactBlocks not implemented for ElectrumX due to being specific to zcash"); + } + /** * Returns list of raw block headers, starting from startHeight inclusive. *

@@ -222,6 +239,17 @@ public class ElectrumX extends BitcoinyBlockchainProvider { return rawBlockHeaders; } + /** + * Returns list of raw block timestamps, starting from startHeight inclusive. + *

+ * @throws ForeignBlockchainException if error occurs + */ + @Override + public List getBlockTimestamps(int startHeight, int count) throws ForeignBlockchainException { + // FUTURE: implement this if needed. For now we use getRawBlockHeaders directly + throw new ForeignBlockchainException("getBlockTimestamps not yet implemented for ElectrumX"); + } + /** * Returns confirmed balance, based on passed payment script. *

@@ -247,6 +275,29 @@ public class ElectrumX extends BitcoinyBlockchainProvider { return (Long) balanceJson.get("confirmed"); } + /** + * Returns confirmed balance, based on passed base58 encoded address. + *

+ * @return confirmed balance, or zero if address unknown + * @throws ForeignBlockchainException if there was an error + */ + @Override + public long getConfirmedAddressBalance(String base58Address) throws ForeignBlockchainException { + throw new ForeignBlockchainException("getConfirmedAddressBalance not yet implemented for ElectrumX"); + } + + /** + * Returns list of unspent outputs pertaining to passed address. + *

+ * @return list of unspent outputs, or empty list if address unknown + * @throws ForeignBlockchainException if there was an error. + */ + @Override + public List getUnspentOutputs(String address, boolean includeUnconfirmed) throws ForeignBlockchainException { + byte[] script = this.blockchain.addressToScriptPubKey(address); + return this.getUnspentOutputs(script, includeUnconfirmed); + } + /** * Returns list of unspent outputs pertaining to passed payment script. *

@@ -482,6 +533,12 @@ public class ElectrumX extends BitcoinyBlockchainProvider { return transactionHashes; } + @Override + public List getAddressBitcoinyTransactions(String address, boolean includeUnconfirmed) throws ForeignBlockchainException { + // FUTURE: implement this if needed. For now we use getAddressTransactions() + getTransaction() + throw new ForeignBlockchainException("getAddressBitcoinyTransactions not yet implemented for ElectrumX"); + } + /** * Broadcasts raw transaction to network. *

@@ -682,6 +739,10 @@ public class ElectrumX extends BitcoinyBlockchainProvider { } catch (IOException | NoSuchElementException e) { // Unable to send, or receive -- try another server? return null; + } catch (NoSuchMethodError e) { + // Likely an SSL dependency issue - retries are unlikely to succeed + LOGGER.error("ElectrumX output stream error", e); + return null; } long endTime = System.currentTimeMillis(); diff --git a/src/main/java/org/qortal/crosschain/LegacyZcashAddress.java b/src/main/java/org/qortal/crosschain/LegacyZcashAddress.java new file mode 100644 index 00000000..14958242 --- /dev/null +++ b/src/main/java/org/qortal/crosschain/LegacyZcashAddress.java @@ -0,0 +1,254 @@ +/* + * Copyright 2011 Google Inc. + * Copyright 2014 Giannis Dzegoutanis + * Copyright 2015 Andreas Schildbach + * + * 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. + */ + +/* Updated for Zcash in May 2022 by Qortal core dev team. Modifications allow +* correct encoding of P2SH (t3) addresses only. */ + +package org.qortal.crosschain; + +import org.bitcoinj.core.*; +import org.bitcoinj.params.Networks; +import org.bitcoinj.script.Script.ScriptType; + +import javax.annotation.Nullable; +import java.util.Arrays; +import java.util.Objects; + +/** + *

A Bitcoin address looks like 1MsScoe2fTJoq4ZPdQgqyhgWeoNamYPevy and is derived from an elliptic curve public key + * plus a set of network parameters. Not to be confused with a {@link PeerAddress} or {@link AddressMessage} + * which are about network (TCP) addresses.

+ * + *

A standard address is built by taking the RIPE-MD160 hash of the public key bytes, with a version prefix and a + * checksum suffix, then encoding it textually as base58. The version prefix is used to both denote the network for + * which the address is valid (see {@link NetworkParameters}, and also to indicate how the bytes inside the address + * should be interpreted. Whilst almost all addresses today are hashes of public keys, another (currently unsupported + * type) can contain a hash of a script instead.

+ */ +public class LegacyZcashAddress extends Address { + /** + * An address is a RIPEMD160 hash of a public key, therefore is always 160 bits or 20 bytes. + */ + public static final int LENGTH = 20; + + /** True if P2SH, false if P2PKH. */ + public final boolean p2sh; + + /* Zcash P2SH header bytes */ + private static int P2SH_HEADER_1 = 28; + private static int P2SH_HEADER_2 = 189; + + /** + * Private constructor. Use {@link #fromBase58(NetworkParameters, String)}, + * {@link #fromPubKeyHash(NetworkParameters, byte[])}, {@link #fromScriptHash(NetworkParameters, byte[])} or + * {@link #fromKey(NetworkParameters, ECKey)}. + * + * @param params + * network this address is valid for + * @param p2sh + * true if hash160 is hash of a script, false if it is hash of a pubkey + * @param hash160 + * 20-byte hash of pubkey or script + */ + private LegacyZcashAddress(NetworkParameters params, boolean p2sh, byte[] hash160) throws AddressFormatException { + super(params, hash160); + if (hash160.length != 20) + throw new AddressFormatException.InvalidDataLength( + "Legacy addresses are 20 byte (160 bit) hashes, but got: " + hash160.length); + this.p2sh = p2sh; + } + + /** + * Construct a {@link LegacyZcashAddress} that represents the given pubkey hash. The resulting address will be a P2PKH type of + * address. + * + * @param params + * network this address is valid for + * @param hash160 + * 20-byte pubkey hash + * @return constructed address + */ + public static LegacyZcashAddress fromPubKeyHash(NetworkParameters params, byte[] hash160) throws AddressFormatException { + return new LegacyZcashAddress(params, false, hash160); + } + + /** + * Construct a {@link LegacyZcashAddress} that represents the public part of the given {@link ECKey}. Note that an address is + * derived from a hash of the public key and is not the public key itself. + * + * @param params + * network this address is valid for + * @param key + * only the public part is used + * @return constructed address + */ + public static LegacyZcashAddress fromKey(NetworkParameters params, ECKey key) { + return fromPubKeyHash(params, key.getPubKeyHash()); + } + + /** + * Construct a {@link LegacyZcashAddress} that represents the given P2SH script hash. + * + * @param params + * network this address is valid for + * @param hash160 + * P2SH script hash + * @return constructed address + */ + public static LegacyZcashAddress fromScriptHash(NetworkParameters params, byte[] hash160) throws AddressFormatException { + return new LegacyZcashAddress(params, true, hash160); + } + + /** + * Construct a {@link LegacyZcashAddress} from its base58 form. + * + * @param params + * expected network this address is valid for, or null if if the network should be derived from the + * base58 + * @param base58 + * base58-encoded textual form of the address + * @throws AddressFormatException + * if the given base58 doesn't parse or the checksum is invalid + * @throws AddressFormatException.WrongNetwork + * if the given address is valid but for a different chain (eg testnet vs mainnet) + */ + public static LegacyZcashAddress fromBase58(@Nullable NetworkParameters params, String base58) + throws AddressFormatException, AddressFormatException.WrongNetwork { + byte[] versionAndDataBytes = Base58.decodeChecked(base58); + int version = versionAndDataBytes[0] & 0xFF; + byte[] bytes = Arrays.copyOfRange(versionAndDataBytes, 1, versionAndDataBytes.length); + if (params == null) { + for (NetworkParameters p : Networks.get()) { + if (version == p.getAddressHeader()) + return new LegacyZcashAddress(p, false, bytes); + else if (version == p.getP2SHHeader()) + return new LegacyZcashAddress(p, true, bytes); + } + throw new AddressFormatException.InvalidPrefix("No network found for " + base58); + } else { + if (version == params.getAddressHeader()) + return new LegacyZcashAddress(params, false, bytes); + else if (version == params.getP2SHHeader()) + return new LegacyZcashAddress(params, true, bytes); + throw new AddressFormatException.WrongNetwork(version); + } + } + + /** + * Get the version header of an address. This is the first byte of a base58 encoded address. + * + * @return version header as one byte + */ + public int getVersion() { + return p2sh ? params.getP2SHHeader() : params.getAddressHeader(); + } + + /** + * Returns the base58-encoded textual form, including version and checksum bytes. + * + * @return textual form + */ + public String toBase58() { + return this.encodeChecked(getVersion(), bytes); + } + + /** The (big endian) 20 byte hash that is the core of a Bitcoin address. */ + @Override + public byte[] getHash() { + return bytes; + } + + /** + * Get the type of output script that will be used for sending to the address. This is either + * {@link ScriptType#P2PKH} or {@link ScriptType#P2SH}. + * + * @return type of output script + */ + @Override + public ScriptType getOutputScriptType() { + return p2sh ? ScriptType.P2SH : ScriptType.P2PKH; + } + + /** + * Given an address, examines the version byte and attempts to find a matching NetworkParameters. If you aren't sure + * which network the address is intended for (eg, it was provided by a user), you can use this to decide if it is + * compatible with the current wallet. + * + * @return network the address is valid for + * @throws AddressFormatException if the given base58 doesn't parse or the checksum is invalid + */ + public static NetworkParameters getParametersFromAddress(String address) throws AddressFormatException { + return LegacyZcashAddress.fromBase58(null, address).getParameters(); + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + LegacyZcashAddress other = (LegacyZcashAddress) o; + return super.equals(other) && this.p2sh == other.p2sh; + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), p2sh); + } + + @Override + public String toString() { + return toBase58(); + } + + @Override + public LegacyZcashAddress clone() throws CloneNotSupportedException { + return (LegacyZcashAddress) super.clone(); + } + + public static String encodeChecked(int version, byte[] payload) { + if (version < 0 || version > 255) + throw new IllegalArgumentException("Version not in range."); + + // A stringified buffer is: + // 1 byte version + data bytes + 4 bytes check code (a truncated hash) + byte[] addressBytes = new byte[2 + payload.length + 4]; + addressBytes[0] = (byte) P2SH_HEADER_1; + addressBytes[1] = (byte) P2SH_HEADER_2; + System.arraycopy(payload, 0, addressBytes, 2, payload.length); + byte[] checksum = Sha256Hash.hashTwice(addressBytes, 0, payload.length + 2); + System.arraycopy(checksum, 0, addressBytes, payload.length + 2, 4); + return Base58.encode(addressBytes); + } + +// // Comparator for LegacyAddress, left argument must be LegacyAddress, right argument can be any Address +// private static final Comparator
LEGACY_ADDRESS_COMPARATOR = Address.PARTIAL_ADDRESS_COMPARATOR +// .thenComparingInt(a -> ((LegacyZcashAddress) a).getVersion()) // Then compare Legacy address version byte +// .thenComparing(a -> a.bytes, UnsignedBytes.lexicographicalComparator()); // Then compare Legacy bytes +// +// /** +// * {@inheritDoc} +// * +// * @param o other {@code Address} object +// * @return comparison result +// */ +// @Override +// public int compareTo(Address o) { +// return LEGACY_ADDRESS_COMPARATOR.compare(this, o); +// } +} diff --git a/src/main/java/org/qortal/crosschain/Litecoin.java b/src/main/java/org/qortal/crosschain/Litecoin.java index 02dd466f..3ab30b2b 100644 --- a/src/main/java/org/qortal/crosschain/Litecoin.java +++ b/src/main/java/org/qortal/crosschain/Litecoin.java @@ -145,6 +145,8 @@ public class Litecoin extends Bitcoiny { Context bitcoinjContext = new Context(litecoinNet.getParams()); instance = new Litecoin(litecoinNet, electrumX, bitcoinjContext, CURRENCY_CODE); + + electrumX.setBlockchain(instance); } return instance; diff --git a/src/main/java/org/qortal/crosschain/PirateChain.java b/src/main/java/org/qortal/crosschain/PirateChain.java new file mode 100644 index 00000000..97aa07fe --- /dev/null +++ b/src/main/java/org/qortal/crosschain/PirateChain.java @@ -0,0 +1,647 @@ +package org.qortal.crosschain; + +import cash.z.wallet.sdk.rpc.CompactFormats; +import com.google.common.hash.HashCode; +import com.rust.litewalletjni.LiteWalletJni; +import org.bitcoinj.core.*; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.libdohj.params.LitecoinRegTestParams; +import org.libdohj.params.LitecoinTestNet3Params; +import org.libdohj.params.PirateChainMainNetParams; +import org.qortal.api.model.crosschain.PirateChainSendRequest; +import org.qortal.controller.PirateChainWalletController; +import org.qortal.crosschain.PirateLightClient.Server; +import org.qortal.crosschain.PirateLightClient.Server.ConnectionType; +import org.qortal.crypto.Crypto; +import org.qortal.settings.Settings; +import org.qortal.transform.TransformationException; +import org.qortal.utils.BitTwiddling; + +import java.nio.ByteBuffer; +import java.util.*; + +public class PirateChain extends Bitcoiny { + + public static final String CURRENCY_CODE = "ARRR"; + + private static final Coin DEFAULT_FEE_PER_KB = Coin.valueOf(10000); // 0.0001 ARRR per 1000 bytes + + private static final long MINIMUM_ORDER_AMOUNT = 10000; // 0.0001 ARRR minimum order, to avoid dust errors // TODO: increase this + + // Temporary values until a dynamic fee system is written. + private static final long MAINNET_FEE = 10000L; // 0.0001 ARRR + private static final long NON_MAINNET_FEE = 10000L; // 0.0001 ARRR + + private static final Map DEFAULT_LITEWALLET_PORTS = new EnumMap<>(ConnectionType.class); + static { + DEFAULT_LITEWALLET_PORTS.put(ConnectionType.TCP, 9067); + DEFAULT_LITEWALLET_PORTS.put(ConnectionType.SSL, 443); + } + + public enum PirateChainNet { + MAIN { + @Override + public NetworkParameters getParams() { + return PirateChainMainNetParams.get(); + } + + @Override + public Collection getServers() { + return Arrays.asList( + // Servers chosen on NO BASIS WHATSOEVER from various sources! + new Server("arrrlightd.qortal.online", ConnectionType.SSL, 443), + new Server("arrrlightd1.qortal.online", ConnectionType.SSL, 443), + new Server("arrrlightd2.qortal.online", ConnectionType.SSL, 443), + new Server("lightd.pirate.black", ConnectionType.SSL, 443)); + } + + @Override + public String getGenesisHash() { + return "027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71"; + } + + @Override + public long getP2shFee(Long timestamp) { + // TODO: This will need to be replaced with something better in the near future! + return MAINNET_FEE; + } + }, + TEST3 { + @Override + public NetworkParameters getParams() { + return LitecoinTestNet3Params.get(); + } + + @Override + public Collection getServers() { + return Arrays.asList(); + } + + @Override + public String getGenesisHash() { + return "4966625a4b2851d9fdee139e56211a0d88575f59ed816ff5e6a63deb4e3e29a0"; + } + + @Override + public long getP2shFee(Long timestamp) { + return NON_MAINNET_FEE; + } + }, + REGTEST { + @Override + public NetworkParameters getParams() { + return LitecoinRegTestParams.get(); + } + + @Override + public Collection getServers() { + return Arrays.asList( + new Server("localhost", ConnectionType.TCP, 9067), + new Server("localhost", ConnectionType.SSL, 443)); + } + + @Override + public String getGenesisHash() { + // This is unique to each regtest instance + return null; + } + + @Override + public long getP2shFee(Long timestamp) { + return NON_MAINNET_FEE; + } + }; + + public abstract NetworkParameters getParams(); + public abstract Collection getServers(); + public abstract String getGenesisHash(); + public abstract long getP2shFee(Long timestamp) throws ForeignBlockchainException; + } + + private static PirateChain instance; + + private final PirateChainNet pirateChainNet; + + // Constructors and instance + + private PirateChain(PirateChainNet pirateChainNet, BitcoinyBlockchainProvider blockchain, Context bitcoinjContext, String currencyCode) { + super(blockchain, bitcoinjContext, currencyCode); + this.pirateChainNet = pirateChainNet; + + LOGGER.info(() -> String.format("Starting Pirate Chain support using %s", this.pirateChainNet.name())); + } + + public static synchronized PirateChain getInstance() { + if (instance == null) { + PirateChainNet pirateChainNet = Settings.getInstance().getPirateChainNet(); + + BitcoinyBlockchainProvider pirateLightClient = new PirateLightClient("PirateChain-" + pirateChainNet.name(), pirateChainNet.getGenesisHash(), pirateChainNet.getServers(), DEFAULT_LITEWALLET_PORTS); + Context bitcoinjContext = new Context(pirateChainNet.getParams()); + + instance = new PirateChain(pirateChainNet, pirateLightClient, bitcoinjContext, CURRENCY_CODE); + + pirateLightClient.setBlockchain(instance); + } + + return instance; + } + + // Getters & setters + + public static synchronized void resetForTesting() { + instance = null; + } + + // Actual useful methods for use by other classes + + /** Default Litecoin fee is lower than Bitcoin: only 10sats/byte. */ + @Override + public Coin getFeePerKb() { + return DEFAULT_FEE_PER_KB; + } + + @Override + public long getMinimumOrderAmount() { + return MINIMUM_ORDER_AMOUNT; + } + + /** + * Returns estimated LTC fee, in sats per 1000bytes, optionally for historic timestamp. + * + * @param timestamp optional milliseconds since epoch, or null for 'now' + * @return sats per 1000bytes, or throws ForeignBlockchainException if something went wrong + */ + @Override + public long getP2shFee(Long timestamp) throws ForeignBlockchainException { + return this.pirateChainNet.getP2shFee(timestamp); + } + + /** + * Returns confirmed balance, based on passed payment script. + *

+ * @return confirmed balance, or zero if balance unknown + * @throws ForeignBlockchainException if there was an error + */ + public long getConfirmedBalance(String base58Address) throws ForeignBlockchainException { + return this.blockchainProvider.getConfirmedAddressBalance(base58Address); + } + + /** + * Returns median timestamp from latest 11 blocks, in seconds. + *

+ * @throws ForeignBlockchainException if error occurs + */ + @Override + public int getMedianBlockTime() throws ForeignBlockchainException { + int height = this.blockchainProvider.getCurrentHeight(); + + // Grab latest 11 blocks + List blockTimestamps = this.blockchainProvider.getBlockTimestamps(height - 11, 11); + if (blockTimestamps.size() < 11) + throw new ForeignBlockchainException("Not enough blocks to determine median block time"); + + // Descending order + blockTimestamps.sort((a, b) -> Long.compare(b, a)); + + // Pick median + return Math.toIntExact(blockTimestamps.get(5)); + } + + /** + * Returns list of compact blocks + *

+ * @throws ForeignBlockchainException if error occurs + */ + public List getCompactBlocks(int startHeight, int count) throws ForeignBlockchainException { + return this.blockchainProvider.getCompactBlocks(startHeight, count); + } + + + @Override + public boolean isValidAddress(String address) { + // Start with some simple checks + if (address == null || !address.toLowerCase().startsWith("zs") || address.length() != 78) { + return false; + } + + // Now try Bech32 decoding the address (which includes checksum verification) + try { + Bech32.Bech32Data decoded = Bech32.decode(address); + return (decoded != null && Objects.equals("zs", decoded.hrp)); + } + catch (AddressFormatException e) { + // Invalid address, checksum failed, etc + return false; + } + } + + @Override + public boolean isValidWalletKey(String walletKey) { + // For Pirate Chain, we only care that the key is a random string + // 32 characters in length, as it is used as entropy for the seed. + return walletKey != null && Base58.decode(walletKey).length == 32; + } + + /** Returns 't3' prefixed P2SH address using passed redeem script. */ + public String deriveP2shAddress(byte[] redeemScriptBytes) { + Context.propagate(bitcoinjContext); + byte[] redeemScriptHash = Crypto.hash160(redeemScriptBytes); + return LegacyZcashAddress.fromScriptHash(this.params, redeemScriptHash).toString(); + } + + /** Returns 'b' prefixed P2SH address using passed redeem script. */ + public String deriveP2shAddressBPrefix(byte[] redeemScriptBytes) { + Context.propagate(bitcoinjContext); + byte[] redeemScriptHash = Crypto.hash160(redeemScriptBytes); + return LegacyAddress.fromScriptHash(this.params, redeemScriptHash).toString(); + } + + public Long getWalletBalance(String entropy58) throws ForeignBlockchainException { + synchronized (this) { + PirateChainWalletController walletController = PirateChainWalletController.getInstance(); + walletController.initWithEntropy58(entropy58); + walletController.ensureInitialized(); + walletController.ensureSynchronized(); + walletController.ensureNotNullSeed(); + + // Get balance + String response = LiteWalletJni.execute("balance", ""); + JSONObject json = new JSONObject(response); + if (json.has("zbalance")) { + return json.getLong("zbalance"); + } + + throw new ForeignBlockchainException("Unable to determine balance"); + } + } + + public List getWalletTransactions(String entropy58) throws ForeignBlockchainException { + synchronized (this) { + PirateChainWalletController walletController = PirateChainWalletController.getInstance(); + walletController.initWithEntropy58(entropy58); + walletController.ensureInitialized(); + walletController.ensureSynchronized(); + walletController.ensureNotNullSeed(); + + List transactions = new ArrayList<>(); + + // Get transactions list + String response = LiteWalletJni.execute("list", ""); + JSONArray transactionsJson = new JSONArray(response); + if (transactionsJson != null) { + for (int i = 0; i < transactionsJson.length(); i++) { + JSONObject transactionJson = transactionsJson.getJSONObject(i); + + if (transactionJson.has("txid")) { + String txId = transactionJson.getString("txid"); + Long timestamp = transactionJson.getLong("datetime"); + Long amount = transactionJson.getLong("amount"); + Long fee = transactionJson.getLong("fee"); + String memo = null; + + if (transactionJson.has("incoming_metadata")) { + JSONArray incomingMetadatas = transactionJson.getJSONArray("incoming_metadata"); + if (incomingMetadatas != null) { + for (int j = 0; j < incomingMetadatas.length(); j++) { + JSONObject incomingMetadata = incomingMetadatas.getJSONObject(j); + if (incomingMetadata.has("value")) { + //String address = incomingMetadata.getString("address"); + Long value = incomingMetadata.getLong("value"); + amount = value; // TODO: figure out how to parse transactions with multiple incomingMetadata entries + } + + if (incomingMetadata.has("memo") && !incomingMetadata.isNull("memo")) { + memo = incomingMetadata.getString("memo"); + } + } + } + } + + if (transactionJson.has("outgoing_metadata")) { + JSONArray outgoingMetadatas = transactionJson.getJSONArray("outgoing_metadata"); + for (int j = 0; j < outgoingMetadatas.length(); j++) { + JSONObject outgoingMetadata = outgoingMetadatas.getJSONObject(j); + + if (outgoingMetadata.has("memo") && !outgoingMetadata.isNull("memo")) { + memo = outgoingMetadata.getString("memo"); + } + } + } + + long timestampMillis = Math.toIntExact(timestamp) * 1000L; + SimpleTransaction transaction = new SimpleTransaction(txId, timestampMillis, amount, fee, null, null, memo); + transactions.add(transaction); + } + } + } + + return transactions; + } + } + + public String getWalletAddress(String entropy58) throws ForeignBlockchainException { + synchronized (this) { + PirateChainWalletController walletController = PirateChainWalletController.getInstance(); + walletController.initWithEntropy58(entropy58); + walletController.ensureInitialized(); + walletController.ensureNotNullSeed(); + + return walletController.getCurrentWallet().getWalletAddress(); + } + } + + public String sendCoins(PirateChainSendRequest pirateChainSendRequest) throws ForeignBlockchainException { + PirateChainWalletController walletController = PirateChainWalletController.getInstance(); + walletController.initWithEntropy58(pirateChainSendRequest.entropy58); + walletController.ensureInitialized(); + walletController.ensureSynchronized(); + walletController.ensureNotNullSeed(); + + // Unlock wallet + walletController.getCurrentWallet().unlock(); + + // Build spend + JSONObject txn = new JSONObject(); + txn.put("input", walletController.getCurrentWallet().getWalletAddress()); + txn.put("fee", MAINNET_FEE); + + JSONObject output = new JSONObject(); + output.put("address", pirateChainSendRequest.receivingAddress); + output.put("amount", pirateChainSendRequest.arrrAmount); + output.put("memo", pirateChainSendRequest.memo); + + JSONArray outputs = new JSONArray(); + outputs.put(output); + txn.put("output", outputs); + + String txnString = txn.toString(); + + // Send the coins + String response = LiteWalletJni.execute("send", txnString); + JSONObject json = new JSONObject(response); + try { + if (json.has("txid")) { // Success + return json.getString("txid"); + } + else if (json.has("error")) { + String error = json.getString("error"); + throw new ForeignBlockchainException(error); + } + + } catch (JSONException e) { + throw new ForeignBlockchainException(e.getMessage()); + } + + throw new ForeignBlockchainException("Something went wrong"); + } + + public String fundP2SH(String entropy58, String receivingAddress, long amount, + String redeemScript58) throws ForeignBlockchainException { + + PirateChainWalletController walletController = PirateChainWalletController.getInstance(); + walletController.initWithEntropy58(entropy58); + walletController.ensureInitialized(); + walletController.ensureSynchronized(); + walletController.ensureNotNullSeed(); + + // Unlock wallet + walletController.getCurrentWallet().unlock(); + + // Build spend + JSONObject txn = new JSONObject(); + txn.put("input", walletController.getCurrentWallet().getWalletAddress()); + txn.put("fee", MAINNET_FEE); + + JSONObject output = new JSONObject(); + output.put("address", receivingAddress); + output.put("amount", amount); + //output.put("memo", memo); + + JSONArray outputs = new JSONArray(); + outputs.put(output); + txn.put("output", outputs); + txn.put("script", redeemScript58); + + String txnString = txn.toString(); + + // Send the coins + String response = LiteWalletJni.execute("sendp2sh", txnString); + JSONObject json = new JSONObject(response); + try { + if (json.has("txid")) { // Success + return json.getString("txid"); + } + else if (json.has("error")) { + String error = json.getString("error"); + throw new ForeignBlockchainException(error); + } + + } catch (JSONException e) { + throw new ForeignBlockchainException(e.getMessage()); + } + + throw new ForeignBlockchainException("Something went wrong"); + } + + public String redeemP2sh(String p2shAddress, String receivingAddress, long amount, String redeemScript58, + String fundingTxid58, String secret58, String privateKey58) throws ForeignBlockchainException { + + // Use null seed wallet since we may not have the entropy bytes for a real wallet's seed + PirateChainWalletController walletController = PirateChainWalletController.getInstance(); + walletController.initNullSeedWallet(); + walletController.ensureInitialized(); + + walletController.getCurrentWallet().unlock(); + + // Build spend + JSONObject txn = new JSONObject(); + txn.put("input", p2shAddress); + txn.put("fee", MAINNET_FEE); + + JSONObject output = new JSONObject(); + output.put("address", receivingAddress); + output.put("amount", amount); + // output.put("memo", ""); // Maybe useful in future to include trade details? + + JSONArray outputs = new JSONArray(); + outputs.put(output); + txn.put("output", outputs); + + txn.put("script", redeemScript58); + txn.put("txid", fundingTxid58); + txn.put("locktime", 0); // Must be 0 when redeeming + txn.put("secret", secret58); + txn.put("privkey", privateKey58); + + String txnString = txn.toString(); + + // Redeem the P2SH + String response = LiteWalletJni.execute("redeemp2sh", txnString); + JSONObject json = new JSONObject(response); + try { + if (json.has("txid")) { // Success + return json.getString("txid"); + } + else if (json.has("error")) { + String error = json.getString("error"); + throw new ForeignBlockchainException(error); + } + + } catch (JSONException e) { + throw new ForeignBlockchainException(e.getMessage()); + } + + throw new ForeignBlockchainException("Something went wrong"); + } + + public String refundP2sh(String p2shAddress, String receivingAddress, long amount, String redeemScript58, + String fundingTxid58, int lockTime, String privateKey58) throws ForeignBlockchainException { + + // Use null seed wallet since we may not have the entropy bytes for a real wallet's seed + PirateChainWalletController walletController = PirateChainWalletController.getInstance(); + walletController.initNullSeedWallet(); + walletController.ensureInitialized(); + + walletController.getCurrentWallet().unlock(); + + // Build spend + JSONObject txn = new JSONObject(); + txn.put("input", p2shAddress); + txn.put("fee", MAINNET_FEE); + + JSONObject output = new JSONObject(); + output.put("address", receivingAddress); + output.put("amount", amount); + // output.put("memo", ""); // Maybe useful in future to include trade details? + + JSONArray outputs = new JSONArray(); + outputs.put(output); + txn.put("output", outputs); + + txn.put("script", redeemScript58); + txn.put("txid", fundingTxid58); + txn.put("locktime", lockTime); + txn.put("secret", ""); // Must be blank when refunding + txn.put("privkey", privateKey58); + + String txnString = txn.toString(); + + // Redeem the P2SH + String response = LiteWalletJni.execute("redeemp2sh", txnString); + JSONObject json = new JSONObject(response); + try { + if (json.has("txid")) { // Success + return json.getString("txid"); + } + else if (json.has("error")) { + String error = json.getString("error"); + throw new ForeignBlockchainException(error); + } + + } catch (JSONException e) { + throw new ForeignBlockchainException(e.getMessage()); + } + + throw new ForeignBlockchainException("Something went wrong"); + } + + public String getSyncStatus(String entropy58) throws ForeignBlockchainException { + synchronized (this) { + PirateChainWalletController walletController = PirateChainWalletController.getInstance(); + walletController.initWithEntropy58(entropy58); + + return walletController.getSyncStatus(); + } + } + + public static BitcoinyTransaction deserializeRawTransaction(String rawTransactionHex) throws TransformationException { + byte[] rawTransactionData = HashCode.fromString(rawTransactionHex).asBytes(); + ByteBuffer byteBuffer = ByteBuffer.wrap(rawTransactionData); + + // Header + int header = BitTwiddling.readU32(byteBuffer); + boolean overwintered = ((header >> 31 & 0xff) == 255); + int version = header & 0x7FFFFFFF; + + // Version group ID + int versionGroupId = 0; + if (overwintered) { + versionGroupId = BitTwiddling.readU32(byteBuffer); + } + + boolean isOverwinterV3 = overwintered && versionGroupId == 0x03C48270 && version == 3; + boolean isSaplingV4 = overwintered && versionGroupId == 0x892F2085 && version == 4; + if (overwintered && !(isOverwinterV3 || isSaplingV4)) { + throw new TransformationException("Unknown transaction format"); + } + + // Inputs + List inputs = new ArrayList<>(); + int vinCount = BitTwiddling.readU8(byteBuffer); + for (int i=0; i outputs = new ArrayList<>(); + int voutCount = BitTwiddling.readU8(byteBuffer); + for (int i=0; i + *

    + *
  • Bob generates PirateChain & Qortal 'trade' keys + *
      + *
    • private key required to sign P2SH redeem tx
    • + *
    • private key could be used to create 'secret' (e.g. double-SHA256)
    • + *
    • encrypted private key could be stored in Qortal AT for access by Bob from any node
    • + *
    + *
  • + *
  • Bob deploys Qortal AT + *
      + *
    + *
  • + *
  • Alice finds Qortal AT and wants to trade + *
      + *
    • Alice generates PirateChain & Qortal 'trade' keys
    • + *
    • Alice funds PirateChain P2SH-A
    • + *
    • Alice sends 'offer' MESSAGE to Bob from her Qortal trade address, containing: + *
        + *
      • hash-of-secret-A
      • + *
      • her 'trade' Pirate Chain public key
      • + *
      + *
    • + *
    + *
  • + *
  • Bob receives "offer" MESSAGE + *
      + *
    • Checks Alice's P2SH-A
    • + *
    • Sends 'trade' MESSAGE to Qortal AT from his trade address, containing: + *
        + *
      • Alice's trade Qortal address
      • + *
      • Alice's trade Pirate Chain public key
      • + *
      • hash-of-secret-A
      • + *
      + *
    • + *
    + *
  • + *
  • Alice checks Qortal AT to confirm it's locked to her + *
      + *
    • Alice sends 'redeem' MESSAGE to Qortal AT from her trade address, containing: + *
        + *
      • secret-A
      • + *
      • Qortal receiving address of her chosing
      • + *
      + *
    • + *
    • AT's QORT funds are sent to Qortal receiving address
    • + *
    + *
  • + *
  • Bob checks AT, extracts secret-A + *
      + *
    • Bob redeems P2SH-A using his PirateChain trade key and secret-A
    • + *
    • P2SH-A ARRR funds end up at PirateChain address determined by redeem transaction output(s)
    • + *
    + *
  • + *
+ */ +public class PirateChainACCTv3 implements ACCT { + + public static final String NAME = PirateChainACCTv3.class.getSimpleName(); + public static final byte[] CODE_BYTES_HASH = HashCode.fromString("fc2818ac0819ab658a065ab0d050e75f167921e2dce5969b9b7741e47e477d83").asBytes(); // SHA256 of AT code bytes + + public static final int SECRET_LENGTH = 32; + + /** Value offset into AT segment where 'mode' variable (long) is stored. (Multiply by MachineState.VALUE_SIZE for byte offset). */ + private static final int MODE_VALUE_OFFSET = 68; + /** Byte offset into AT state data where 'mode' variable (long) is stored. */ + public static final int MODE_BYTE_OFFSET = MachineState.HEADER_LENGTH + (MODE_VALUE_OFFSET * MachineState.VALUE_SIZE); + + public static class OfferMessageData { + public byte[] partnerPirateChainPublicKey; + public byte[] hashOfSecretA; + public long lockTimeA; + } + public static final int OFFER_MESSAGE_LENGTH = 33 /*partnerPirateChainPublicKey*/ + 20 /*hashOfSecretA*/ + 8 /*lockTimeA*/; + public static final int TRADE_MESSAGE_LENGTH = 32 /*partner's Qortal trade address (padded from 25 to 32)*/ + + 40 /*partner's Pirate Chain public key (padded from 33 to 40)*/ + + 8 /*AT trade timeout (minutes)*/ + + 24 /*hash of secret-A (padded from 20 to 24)*/ + + 8 /*lockTimeA*/; + public static final int REDEEM_MESSAGE_LENGTH = 32 /*secret-A*/ + 32 /*partner's Qortal receiving address padded from 25 to 32*/; + public static final int CANCEL_MESSAGE_LENGTH = 32 /*AT creator's Qortal address*/; + + private static PirateChainACCTv3 instance; + + private PirateChainACCTv3() { + } + + public static synchronized PirateChainACCTv3 getInstance() { + if (instance == null) + instance = new PirateChainACCTv3(); + + return instance; + } + + @Override + public byte[] getCodeBytesHash() { + return CODE_BYTES_HASH; + } + + @Override + public int getModeByteOffset() { + return MODE_BYTE_OFFSET; + } + + @Override + public ForeignBlockchain getBlockchain() { + return PirateChain.getInstance(); + } + + /** + * Returns Qortal AT creation bytes for cross-chain trading AT. + *

+ * tradeTimeout (minutes) is the time window for the trade partner to send the + * 32-byte secret to the AT, before the AT automatically refunds the AT's creator. + * + * @param creatorTradeAddress AT creator's trade Qortal address + * @param pirateChainPublicKeyHash 33-byte creator's trade PirateChain public key + * @param qortAmount how much QORT to pay trade partner if they send correct 32-byte secrets to AT + * @param arrrAmount how much ARRR the AT creator is expecting to trade + * @param tradeTimeout suggested timeout for entire trade + */ + public static byte[] buildQortalAT(String creatorTradeAddress, byte[] pirateChainPublicKeyHash, long qortAmount, long arrrAmount, int tradeTimeout) { + if (pirateChainPublicKeyHash.length != 33) + throw new IllegalArgumentException("PirateChain public key hash should be 33 bytes"); + + // Labels for data segment addresses + int addrCounter = 0; + + // Constants (with corresponding dataByteBuffer.put*() calls below) + + final int addrCreatorTradeAddress1 = addrCounter++; + final int addrCreatorTradeAddress2 = addrCounter++; + final int addrCreatorTradeAddress3 = addrCounter++; + final int addrCreatorTradeAddress4 = addrCounter++; + + final int addrPirateChainPublicKeyHash = addrCounter; + addrCounter += 5; + + final int addrQortAmount = addrCounter++; + final int addrarrrAmount = addrCounter++; + final int addrTradeTimeout = addrCounter++; + + final int addrMessageTxnType = addrCounter++; + final int addrExpectedTradeMessageLength = addrCounter++; + final int addrExpectedRedeemMessageLength = addrCounter++; + + final int addrCreatorAddressPointer = addrCounter++; + final int addrQortalPartnerAddressPointer = addrCounter++; + final int addrMessageSenderPointer = addrCounter++; + + final int addrTradeMessagePartnerPirateChainPublicKeyFirst32BytesOffset = addrCounter++; + final int addrTradeMessagePartnerPirateChainPublicKeyLastByteOffset = addrCounter++; // Remainder of public key, plus timeout + final int addrPartnerPirateChainPublicKeyFirst32BytesPointer = addrCounter++; + final int addrPartnerPirateChainPublicKeyLastBytePointer = addrCounter++; // Remainder of public key + final int addrTradeMessageHashOfSecretAOffset = addrCounter++; + final int addrHashOfSecretAPointer = addrCounter++; + + final int addrRedeemMessageReceivingAddressOffset = addrCounter++; + + final int addrMessageDataPointer = addrCounter++; + final int addrMessageDataLength = addrCounter++; + + final int addrPartnerReceivingAddressPointer = addrCounter++; + + final int addrEndOfConstants = addrCounter; + + // Variables + + final int addrCreatorAddress1 = addrCounter++; + final int addrCreatorAddress2 = addrCounter++; + final int addrCreatorAddress3 = addrCounter++; + final int addrCreatorAddress4 = addrCounter++; + + final int addrQortalPartnerAddress1 = addrCounter++; + final int addrQortalPartnerAddress2 = addrCounter++; + final int addrQortalPartnerAddress3 = addrCounter++; + final int addrQortalPartnerAddress4 = addrCounter++; + + final int addrLockTimeA = addrCounter++; + final int addrRefundTimeout = addrCounter++; + final int addrRefundTimestamp = addrCounter++; + final int addrLastTxnTimestamp = addrCounter++; + final int addrBlockTimestamp = addrCounter++; + final int addrTxnType = addrCounter++; + final int addrResult = addrCounter++; + + final int addrMessageSender1 = addrCounter++; + final int addrMessageSender2 = addrCounter++; + final int addrMessageSender3 = addrCounter++; + final int addrMessageSender4 = addrCounter++; + + final int addrMessageLength = addrCounter++; + + final int addrMessageData = addrCounter; + addrCounter += 4; + + final int addrHashOfSecretA = addrCounter; + addrCounter += 4; + + final int addrPartnerPirateChainPublicKeyFirst32Bytes = addrCounter; + addrCounter += 4; + + final int addrPartnerPirateChainPublicKeyLastByte = addrCounter; + addrCounter += 4; // We retrieve using GET_B_IND, so need to allow space for the full 32 bytes + + final int addrPartnerReceivingAddress = addrCounter; + addrCounter += 4; + + final int addrMode = addrCounter++; + assert addrMode == MODE_VALUE_OFFSET : String.format("addrMode %d does not match MODE_VALUE_OFFSET %d", addrMode, MODE_VALUE_OFFSET); + + // Data segment + ByteBuffer dataByteBuffer = ByteBuffer.allocate(addrCounter * MachineState.VALUE_SIZE); + + // AT creator's trade Qortal address, decoded from Base58 + assert dataByteBuffer.position() == addrCreatorTradeAddress1 * MachineState.VALUE_SIZE : "addrCreatorTradeAddress1 incorrect"; + byte[] creatorTradeAddressBytes = Base58.decode(creatorTradeAddress); + dataByteBuffer.put(Bytes.ensureCapacity(creatorTradeAddressBytes, 32, 0)); + + // PirateChain public key hash + assert dataByteBuffer.position() == addrPirateChainPublicKeyHash * MachineState.VALUE_SIZE : "addrPirateChainPublicKeyHash incorrect"; + dataByteBuffer.put(Bytes.ensureCapacity(pirateChainPublicKeyHash, 40, 0)); + + // Redeem Qort amount + assert dataByteBuffer.position() == addrQortAmount * MachineState.VALUE_SIZE : "addrQortAmount incorrect"; + dataByteBuffer.putLong(qortAmount); + + // Expected PirateChain amount + assert dataByteBuffer.position() == addrarrrAmount * MachineState.VALUE_SIZE : "addrarrrAmount incorrect"; + dataByteBuffer.putLong(arrrAmount); + + // Suggested trade timeout (minutes) + assert dataByteBuffer.position() == addrTradeTimeout * MachineState.VALUE_SIZE : "addrTradeTimeout incorrect"; + dataByteBuffer.putLong(tradeTimeout); + + // We're only interested in MESSAGE transactions + assert dataByteBuffer.position() == addrMessageTxnType * MachineState.VALUE_SIZE : "addrMessageTxnType incorrect"; + dataByteBuffer.putLong(API.ATTransactionType.MESSAGE.value); + + // Expected length of 'trade' MESSAGE data from AT creator + assert dataByteBuffer.position() == addrExpectedTradeMessageLength * MachineState.VALUE_SIZE : "addrExpectedTradeMessageLength incorrect"; + dataByteBuffer.putLong(TRADE_MESSAGE_LENGTH); + + // Expected length of 'redeem' MESSAGE data from trade partner + assert dataByteBuffer.position() == addrExpectedRedeemMessageLength * MachineState.VALUE_SIZE : "addrExpectedRedeemMessageLength incorrect"; + dataByteBuffer.putLong(REDEEM_MESSAGE_LENGTH); + + // Index into data segment of AT creator's address, used by GET_B_IND + assert dataByteBuffer.position() == addrCreatorAddressPointer * MachineState.VALUE_SIZE : "addrCreatorAddressPointer incorrect"; + dataByteBuffer.putLong(addrCreatorAddress1); + + // Index into data segment of partner's Qortal address, used by SET_B_IND + assert dataByteBuffer.position() == addrQortalPartnerAddressPointer * MachineState.VALUE_SIZE : "addrQortalPartnerAddressPointer incorrect"; + dataByteBuffer.putLong(addrQortalPartnerAddress1); + + // Index into data segment of (temporary) transaction's sender's address, used by GET_B_IND + assert dataByteBuffer.position() == addrMessageSenderPointer * MachineState.VALUE_SIZE : "addrMessageSenderPointer incorrect"; + dataByteBuffer.putLong(addrMessageSender1); + + // Offset into 'trade' MESSAGE data payload for extracting first 32 bytes of partner's Pirate Chain public key + assert dataByteBuffer.position() == addrTradeMessagePartnerPirateChainPublicKeyFirst32BytesOffset * MachineState.VALUE_SIZE : "addrTradeMessagePartnerPirateChainPublicKeyFirst32BytesOffset incorrect"; + dataByteBuffer.putLong(32L); + + // Offset into 'trade' MESSAGE data payload for extracting last byte of public key + assert dataByteBuffer.position() == addrTradeMessagePartnerPirateChainPublicKeyLastByteOffset * MachineState.VALUE_SIZE : "addrTradeMessagePartnerPirateChainPublicKeyLastByteOffset incorrect"; + dataByteBuffer.putLong(64L); + + // Index into data segment of partner's Pirate Chain public key, used by GET_B_IND + assert dataByteBuffer.position() == addrPartnerPirateChainPublicKeyFirst32BytesPointer * MachineState.VALUE_SIZE : "addrPartnerPirateChainPublicKeyFirst32BytesPointer incorrect"; + dataByteBuffer.putLong(addrPartnerPirateChainPublicKeyFirst32Bytes); + + // Index into data segment of remainder of partner's Pirate Chain public key, used by GET_B_IND + assert dataByteBuffer.position() == addrPartnerPirateChainPublicKeyLastBytePointer * MachineState.VALUE_SIZE : "addrPartnerPirateChainPublicKeyLastBytePointer incorrect"; + dataByteBuffer.putLong(addrPartnerPirateChainPublicKeyLastByte); + + // Offset into 'trade' MESSAGE data payload for extracting hash-of-secret-A + assert dataByteBuffer.position() == addrTradeMessageHashOfSecretAOffset * MachineState.VALUE_SIZE : "addrTradeMessageHashOfSecretAOffset incorrect"; + dataByteBuffer.putLong(80L); + + // Index into data segment to hash of secret A, used by GET_B_IND + assert dataByteBuffer.position() == addrHashOfSecretAPointer * MachineState.VALUE_SIZE : "addrHashOfSecretAPointer incorrect"; + dataByteBuffer.putLong(addrHashOfSecretA); + + // Offset into 'redeem' MESSAGE data payload for extracting Qortal receiving address + assert dataByteBuffer.position() == addrRedeemMessageReceivingAddressOffset * MachineState.VALUE_SIZE : "addrRedeemMessageReceivingAddressOffset incorrect"; + dataByteBuffer.putLong(32L); + + // Source location and length for hashing any passed secret + assert dataByteBuffer.position() == addrMessageDataPointer * MachineState.VALUE_SIZE : "addrMessageDataPointer incorrect"; + dataByteBuffer.putLong(addrMessageData); + assert dataByteBuffer.position() == addrMessageDataLength * MachineState.VALUE_SIZE : "addrMessageDataLength incorrect"; + dataByteBuffer.putLong(32L); + + // Pointer into data segment of where to save partner's receiving Qortal address, used by GET_B_IND + assert dataByteBuffer.position() == addrPartnerReceivingAddressPointer * MachineState.VALUE_SIZE : "addrPartnerReceivingAddressPointer incorrect"; + dataByteBuffer.putLong(addrPartnerReceivingAddress); + + assert dataByteBuffer.position() == addrEndOfConstants * MachineState.VALUE_SIZE : "dataByteBuffer position not at end of constants"; + + // Code labels + Integer labelRefund = null; + + Integer labelTradeTxnLoop = null; + Integer labelCheckTradeTxn = null; + Integer labelCheckCancelTxn = null; + Integer labelNotTradeNorCancelTxn = null; + Integer labelCheckNonRefundTradeTxn = null; + Integer labelTradeTxnExtract = null; + Integer labelRedeemTxnLoop = null; + Integer labelCheckRedeemTxn = null; + Integer labelCheckRedeemTxnSender = null; + Integer labelPayout = null; + + ByteBuffer codeByteBuffer = ByteBuffer.allocate(768); + + // Two-pass version + for (int pass = 0; pass < 2; ++pass) { + codeByteBuffer.clear(); + + try { + /* Initialization */ + + // Use AT creation 'timestamp' as starting point for finding transactions sent to AT + codeByteBuffer.put(OpCode.EXT_FUN_RET.compile(FunctionCode.GET_CREATION_TIMESTAMP, addrLastTxnTimestamp)); + + // Load B register with AT creator's address so we can save it into addrCreatorAddress1-4 + codeByteBuffer.put(OpCode.EXT_FUN.compile(FunctionCode.PUT_CREATOR_INTO_B)); + codeByteBuffer.put(OpCode.EXT_FUN_DAT.compile(FunctionCode.GET_B_IND, addrCreatorAddressPointer)); + + // Set restart position to after this opcode + codeByteBuffer.put(OpCode.SET_PCS.compile()); + + /* Loop, waiting for message from AT creator's trade address containing trade partner details, or AT owner's address to cancel offer */ + + /* Transaction processing loop */ + labelTradeTxnLoop = codeByteBuffer.position(); + + /* Sleep until message arrives */ + codeByteBuffer.put(OpCode.EXT_FUN_DAT.compile(QortalFunctionCode.SLEEP_UNTIL_MESSAGE.value, addrLastTxnTimestamp)); + + // Find next transaction (if any) to this AT since the last one (referenced by addrLastTxnTimestamp) + codeByteBuffer.put(OpCode.EXT_FUN_DAT.compile(FunctionCode.PUT_TX_AFTER_TIMESTAMP_INTO_A, addrLastTxnTimestamp)); + // If no transaction found, A will be zero. If A is zero, set addrResult to 1, otherwise 0. + codeByteBuffer.put(OpCode.EXT_FUN_RET.compile(FunctionCode.CHECK_A_IS_ZERO, addrResult)); + // If addrResult is zero (i.e. A is non-zero, transaction was found) then go check transaction + codeByteBuffer.put(OpCode.BZR_DAT.compile(addrResult, calcOffset(codeByteBuffer, labelCheckTradeTxn))); + // Stop and wait for next block + codeByteBuffer.put(OpCode.STP_IMD.compile()); + + /* Check transaction */ + labelCheckTradeTxn = codeByteBuffer.position(); + + // Update our 'last found transaction's timestamp' using 'timestamp' from transaction + codeByteBuffer.put(OpCode.EXT_FUN_RET.compile(FunctionCode.GET_TIMESTAMP_FROM_TX_IN_A, addrLastTxnTimestamp)); + // Extract transaction type (message/payment) from transaction and save type in addrTxnType + codeByteBuffer.put(OpCode.EXT_FUN_RET.compile(FunctionCode.GET_TYPE_FROM_TX_IN_A, addrTxnType)); + // If transaction type is not MESSAGE type then go look for another transaction + codeByteBuffer.put(OpCode.BNE_DAT.compile(addrTxnType, addrMessageTxnType, calcOffset(codeByteBuffer, labelTradeTxnLoop))); + + /* Check transaction's sender. We're expecting AT creator's trade address for 'trade' message, or AT creator's own address for 'cancel' message. */ + + // Extract sender address from transaction into B register + codeByteBuffer.put(OpCode.EXT_FUN.compile(FunctionCode.PUT_ADDRESS_FROM_TX_IN_A_INTO_B)); + // Save B register into data segment starting at addrMessageSender1 (as pointed to by addrMessageSenderPointer) + codeByteBuffer.put(OpCode.EXT_FUN_DAT.compile(FunctionCode.GET_B_IND, addrMessageSenderPointer)); + // Compare each part of message sender's address with AT creator's trade address. If they don't match, check for cancel situation. + codeByteBuffer.put(OpCode.BNE_DAT.compile(addrMessageSender1, addrCreatorTradeAddress1, calcOffset(codeByteBuffer, labelCheckCancelTxn))); + codeByteBuffer.put(OpCode.BNE_DAT.compile(addrMessageSender2, addrCreatorTradeAddress2, calcOffset(codeByteBuffer, labelCheckCancelTxn))); + codeByteBuffer.put(OpCode.BNE_DAT.compile(addrMessageSender3, addrCreatorTradeAddress3, calcOffset(codeByteBuffer, labelCheckCancelTxn))); + codeByteBuffer.put(OpCode.BNE_DAT.compile(addrMessageSender4, addrCreatorTradeAddress4, calcOffset(codeByteBuffer, labelCheckCancelTxn))); + // Message sender's address matches AT creator's trade address so go process 'trade' message + codeByteBuffer.put(OpCode.JMP_ADR.compile(labelCheckNonRefundTradeTxn == null ? 0 : labelCheckNonRefundTradeTxn)); + + /* Checking message sender for possible cancel message */ + labelCheckCancelTxn = codeByteBuffer.position(); + + // Compare each part of message sender's address with AT creator's address. If they don't match, look for another transaction. + codeByteBuffer.put(OpCode.BNE_DAT.compile(addrMessageSender1, addrCreatorAddress1, calcOffset(codeByteBuffer, labelNotTradeNorCancelTxn))); + codeByteBuffer.put(OpCode.BNE_DAT.compile(addrMessageSender2, addrCreatorAddress2, calcOffset(codeByteBuffer, labelNotTradeNorCancelTxn))); + codeByteBuffer.put(OpCode.BNE_DAT.compile(addrMessageSender3, addrCreatorAddress3, calcOffset(codeByteBuffer, labelNotTradeNorCancelTxn))); + codeByteBuffer.put(OpCode.BNE_DAT.compile(addrMessageSender4, addrCreatorAddress4, calcOffset(codeByteBuffer, labelNotTradeNorCancelTxn))); + // Partner address is AT creator's address, so cancel offer and finish. + codeByteBuffer.put(OpCode.SET_VAL.compile(addrMode, AcctMode.CANCELLED.value)); + // We're finished forever (finishing auto-refunds remaining balance to AT creator) + codeByteBuffer.put(OpCode.FIN_IMD.compile()); + + /* Not trade nor cancel message */ + labelNotTradeNorCancelTxn = codeByteBuffer.position(); + + // Loop to find another transaction + codeByteBuffer.put(OpCode.JMP_ADR.compile(labelTradeTxnLoop == null ? 0 : labelTradeTxnLoop)); + + /* Possible switch-to-trade-mode message */ + labelCheckNonRefundTradeTxn = codeByteBuffer.position(); + + // Check 'trade' message we received has expected number of message bytes + codeByteBuffer.put(OpCode.EXT_FUN_RET.compile(QortalFunctionCode.GET_MESSAGE_LENGTH_FROM_TX_IN_A.value, addrMessageLength)); + // If message length matches, branch to info extraction code + codeByteBuffer.put(OpCode.BEQ_DAT.compile(addrMessageLength, addrExpectedTradeMessageLength, calcOffset(codeByteBuffer, labelTradeTxnExtract))); + // Message length didn't match - go back to finding another 'trade' MESSAGE transaction + codeByteBuffer.put(OpCode.JMP_ADR.compile(labelTradeTxnLoop == null ? 0 : labelTradeTxnLoop)); + + /* Extracting info from 'trade' MESSAGE transaction */ + labelTradeTxnExtract = codeByteBuffer.position(); + + // Extract message from transaction into B register + codeByteBuffer.put(OpCode.EXT_FUN.compile(FunctionCode.PUT_MESSAGE_FROM_TX_IN_A_INTO_B)); + // Save B register into data segment starting at addrQortalPartnerAddress1 (as pointed to by addrQortalPartnerAddressPointer) + codeByteBuffer.put(OpCode.EXT_FUN_DAT.compile(FunctionCode.GET_B_IND, addrQortalPartnerAddressPointer)); + + // Extract first 32 bytes of trade partner's Pirate Chain public key from message into B + codeByteBuffer.put(OpCode.EXT_FUN_DAT.compile(QortalFunctionCode.PUT_PARTIAL_MESSAGE_FROM_TX_IN_A_INTO_B.value, addrTradeMessagePartnerPirateChainPublicKeyFirst32BytesOffset)); + // Store first 32 bytes of partner's Pirate Chain public key + codeByteBuffer.put(OpCode.EXT_FUN_DAT.compile(FunctionCode.GET_B_IND, addrPartnerPirateChainPublicKeyFirst32BytesPointer)); + + // Extract last byte of public key, plus trade timeout, from message into B + codeByteBuffer.put(OpCode.EXT_FUN_DAT.compile(QortalFunctionCode.PUT_PARTIAL_MESSAGE_FROM_TX_IN_A_INTO_B.value, addrTradeMessagePartnerPirateChainPublicKeyLastByteOffset)); + // Store last byte of partner's Pirate Chain public key + codeByteBuffer.put(OpCode.EXT_FUN_DAT.compile(FunctionCode.GET_B_IND, addrPartnerPirateChainPublicKeyLastBytePointer)); + // Extract AT trade timeout (minutes) (from B2) + codeByteBuffer.put(OpCode.EXT_FUN_RET.compile(FunctionCode.GET_B2, addrRefundTimeout)); + + // Grab next 32 bytes + codeByteBuffer.put(OpCode.EXT_FUN_DAT.compile(QortalFunctionCode.PUT_PARTIAL_MESSAGE_FROM_TX_IN_A_INTO_B.value, addrTradeMessageHashOfSecretAOffset)); + + // Extract hash-of-secret-A (we only really use values from B1-B3) + codeByteBuffer.put(OpCode.EXT_FUN_DAT.compile(FunctionCode.GET_B_IND, addrHashOfSecretAPointer)); + // Extract lockTime-A (from B4) + codeByteBuffer.put(OpCode.EXT_FUN_RET.compile(FunctionCode.GET_B4, addrLockTimeA)); + + // Calculate trade timeout refund 'timestamp' by adding addrRefundTimeout minutes to this transaction's 'timestamp', then save into addrRefundTimestamp + codeByteBuffer.put(OpCode.EXT_FUN_RET_DAT_2.compile(FunctionCode.ADD_MINUTES_TO_TIMESTAMP, addrRefundTimestamp, addrLastTxnTimestamp, addrRefundTimeout)); + + /* We are in 'trade mode' */ + codeByteBuffer.put(OpCode.SET_VAL.compile(addrMode, AcctMode.TRADING.value)); + + // Set restart position to after this opcode + codeByteBuffer.put(OpCode.SET_PCS.compile()); + + /* Loop, waiting for trade timeout or 'redeem' MESSAGE from Qortal trade partner */ + + // Fetch current block 'timestamp' + codeByteBuffer.put(OpCode.EXT_FUN_RET.compile(FunctionCode.GET_BLOCK_TIMESTAMP, addrBlockTimestamp)); + // If we're not past refund 'timestamp' then look for next transaction + codeByteBuffer.put(OpCode.BLT_DAT.compile(addrBlockTimestamp, addrRefundTimestamp, calcOffset(codeByteBuffer, labelRedeemTxnLoop))); + // We're past refund 'timestamp' so go refund everything back to AT creator + codeByteBuffer.put(OpCode.JMP_ADR.compile(labelRefund == null ? 0 : labelRefund)); + + /* Transaction processing loop */ + labelRedeemTxnLoop = codeByteBuffer.position(); + + // Find next transaction to this AT since the last one (if any) + codeByteBuffer.put(OpCode.EXT_FUN_DAT.compile(FunctionCode.PUT_TX_AFTER_TIMESTAMP_INTO_A, addrLastTxnTimestamp)); + // If no transaction found, A will be zero. If A is zero, set addrComparator to 1, otherwise 0. + codeByteBuffer.put(OpCode.EXT_FUN_RET.compile(FunctionCode.CHECK_A_IS_ZERO, addrResult)); + // If addrResult is zero (i.e. A is non-zero, transaction was found) then go check transaction + codeByteBuffer.put(OpCode.BZR_DAT.compile(addrResult, calcOffset(codeByteBuffer, labelCheckRedeemTxn))); + // Stop and wait for next block + codeByteBuffer.put(OpCode.STP_IMD.compile()); + + /* Check transaction */ + labelCheckRedeemTxn = codeByteBuffer.position(); + + // Update our 'last found transaction's timestamp' using 'timestamp' from transaction + codeByteBuffer.put(OpCode.EXT_FUN_RET.compile(FunctionCode.GET_TIMESTAMP_FROM_TX_IN_A, addrLastTxnTimestamp)); + // Extract transaction type (message/payment) from transaction and save type in addrTxnType + codeByteBuffer.put(OpCode.EXT_FUN_RET.compile(FunctionCode.GET_TYPE_FROM_TX_IN_A, addrTxnType)); + // If transaction type is not MESSAGE type then go look for another transaction + codeByteBuffer.put(OpCode.BNE_DAT.compile(addrTxnType, addrMessageTxnType, calcOffset(codeByteBuffer, labelRedeemTxnLoop))); + + /* Check message payload length */ + codeByteBuffer.put(OpCode.EXT_FUN_RET.compile(QortalFunctionCode.GET_MESSAGE_LENGTH_FROM_TX_IN_A.value, addrMessageLength)); + // If message length matches, branch to sender checking code + codeByteBuffer.put(OpCode.BEQ_DAT.compile(addrMessageLength, addrExpectedRedeemMessageLength, calcOffset(codeByteBuffer, labelCheckRedeemTxnSender))); + // Message length didn't match - go back to finding another 'redeem' MESSAGE transaction + codeByteBuffer.put(OpCode.JMP_ADR.compile(labelRedeemTxnLoop == null ? 0 : labelRedeemTxnLoop)); + + /* Check transaction's sender */ + labelCheckRedeemTxnSender = codeByteBuffer.position(); + + // Extract sender address from transaction into B register + codeByteBuffer.put(OpCode.EXT_FUN.compile(FunctionCode.PUT_ADDRESS_FROM_TX_IN_A_INTO_B)); + // Save B register into data segment starting at addrMessageSender1 (as pointed to by addrMessageSenderPointer) + codeByteBuffer.put(OpCode.EXT_FUN_DAT.compile(FunctionCode.GET_B_IND, addrMessageSenderPointer)); + // Compare each part of transaction's sender's address with expected address. If they don't match, look for another transaction. + codeByteBuffer.put(OpCode.BNE_DAT.compile(addrMessageSender1, addrQortalPartnerAddress1, calcOffset(codeByteBuffer, labelRedeemTxnLoop))); + codeByteBuffer.put(OpCode.BNE_DAT.compile(addrMessageSender2, addrQortalPartnerAddress2, calcOffset(codeByteBuffer, labelRedeemTxnLoop))); + codeByteBuffer.put(OpCode.BNE_DAT.compile(addrMessageSender3, addrQortalPartnerAddress3, calcOffset(codeByteBuffer, labelRedeemTxnLoop))); + codeByteBuffer.put(OpCode.BNE_DAT.compile(addrMessageSender4, addrQortalPartnerAddress4, calcOffset(codeByteBuffer, labelRedeemTxnLoop))); + + /* Check 'secret-A' in transaction's message */ + + // Extract secret-A from first 32 bytes of message from transaction into B register + codeByteBuffer.put(OpCode.EXT_FUN.compile(FunctionCode.PUT_MESSAGE_FROM_TX_IN_A_INTO_B)); + // Save B register into data segment starting at addrMessageData (as pointed to by addrMessageDataPointer) + codeByteBuffer.put(OpCode.EXT_FUN_DAT.compile(FunctionCode.GET_B_IND, addrMessageDataPointer)); + // Load B register with expected hash result (as pointed to by addrHashOfSecretAPointer) + codeByteBuffer.put(OpCode.EXT_FUN_DAT.compile(FunctionCode.SET_B_IND, addrHashOfSecretAPointer)); + // Perform HASH160 using source data at addrMessageData. (Location and length specified via addrMessageDataPointer and addrMessageDataLength). + // Save the equality result (1 if they match, 0 otherwise) into addrResult. + codeByteBuffer.put(OpCode.EXT_FUN_RET_DAT_2.compile(FunctionCode.CHECK_HASH160_WITH_B, addrResult, addrMessageDataPointer, addrMessageDataLength)); + // If hashes don't match, addrResult will be zero so go find another transaction + codeByteBuffer.put(OpCode.BNZ_DAT.compile(addrResult, calcOffset(codeByteBuffer, labelPayout))); + codeByteBuffer.put(OpCode.JMP_ADR.compile(labelRedeemTxnLoop == null ? 0 : labelRedeemTxnLoop)); + + /* Success! Pay arranged amount to receiving address */ + labelPayout = codeByteBuffer.position(); + + // Extract Qortal receiving address from next 32 bytes of message from transaction into B register + codeByteBuffer.put(OpCode.EXT_FUN_DAT.compile(QortalFunctionCode.PUT_PARTIAL_MESSAGE_FROM_TX_IN_A_INTO_B.value, addrRedeemMessageReceivingAddressOffset)); + // Save B register into data segment starting at addrPartnerReceivingAddress (as pointed to by addrPartnerReceivingAddressPointer) + codeByteBuffer.put(OpCode.EXT_FUN_DAT.compile(FunctionCode.GET_B_IND, addrPartnerReceivingAddressPointer)); + // Pay AT's balance to receiving address + codeByteBuffer.put(OpCode.EXT_FUN_DAT.compile(FunctionCode.PAY_TO_ADDRESS_IN_B, addrQortAmount)); + // Set redeemed mode + codeByteBuffer.put(OpCode.SET_VAL.compile(addrMode, AcctMode.REDEEMED.value)); + // We're finished forever (finishing auto-refunds remaining balance to AT creator) + codeByteBuffer.put(OpCode.FIN_IMD.compile()); + + // Fall-through to refunding any remaining balance back to AT creator + + /* Refund balance back to AT creator */ + labelRefund = codeByteBuffer.position(); + + // Set refunded mode + codeByteBuffer.put(OpCode.SET_VAL.compile(addrMode, AcctMode.REFUNDED.value)); + // We're finished forever (finishing auto-refunds remaining balance to AT creator) + codeByteBuffer.put(OpCode.FIN_IMD.compile()); + } catch (CompilationException e) { + throw new IllegalStateException("Unable to compile ARRR-QORT ACCT?", e); + } + } + + codeByteBuffer.flip(); + + byte[] codeBytes = new byte[codeByteBuffer.limit()]; + codeByteBuffer.get(codeBytes); + + assert Arrays.equals(Crypto.digest(codeBytes), PirateChainACCTv3.CODE_BYTES_HASH) + : String.format("BTCACCT.CODE_BYTES_HASH mismatch: expected %s, actual %s", HashCode.fromBytes(CODE_BYTES_HASH), HashCode.fromBytes(Crypto.digest(codeBytes))); + + final short ciyamAtVersion = 2; + final short numCallStackPages = 0; + final short numUserStackPages = 0; + final long minActivationAmount = 0L; + + return MachineState.toCreationBytes(ciyamAtVersion, codeBytes, dataByteBuffer.array(), numCallStackPages, numUserStackPages, minActivationAmount); + } + + /** + * Returns CrossChainTradeData with useful info extracted from AT. + */ + @Override + public CrossChainTradeData populateTradeData(Repository repository, ATData atData) throws DataException { + ATStateData atStateData = repository.getATRepository().getLatestATState(atData.getATAddress()); + return populateTradeData(repository, atData.getCreatorPublicKey(), atData.getCreation(), atStateData); + } + + /** + * Returns CrossChainTradeData with useful info extracted from AT. + */ + @Override + public CrossChainTradeData populateTradeData(Repository repository, ATStateData atStateData) throws DataException { + ATData atData = repository.getATRepository().fromATAddress(atStateData.getATAddress()); + return populateTradeData(repository, atData.getCreatorPublicKey(), atData.getCreation(), atStateData); + } + + /** + * Returns CrossChainTradeData with useful info extracted from AT. + */ + public CrossChainTradeData populateTradeData(Repository repository, byte[] creatorPublicKey, long creationTimestamp, ATStateData atStateData) throws DataException { + byte[] addressBytes = new byte[25]; // for general use + String atAddress = atStateData.getATAddress(); + + CrossChainTradeData tradeData = new CrossChainTradeData(); + + tradeData.foreignBlockchain = SupportedBlockchain.PIRATECHAIN.name(); + tradeData.acctName = NAME; + + tradeData.qortalAtAddress = atAddress; + tradeData.qortalCreator = Crypto.toAddress(creatorPublicKey); + tradeData.creationTimestamp = creationTimestamp; + + Account atAccount = new Account(repository, atAddress); + tradeData.qortBalance = atAccount.getConfirmedBalance(Asset.QORT); + + byte[] stateData = atStateData.getStateData(); + ByteBuffer dataByteBuffer = ByteBuffer.wrap(stateData); + dataByteBuffer.position(MachineState.HEADER_LENGTH); + + /* Constants */ + + // Skip creator's trade address + dataByteBuffer.get(addressBytes); + tradeData.qortalCreatorTradeAddress = Base58.encode(addressBytes); + dataByteBuffer.position(dataByteBuffer.position() + 32 - addressBytes.length); + + // Creator's PirateChain/foreign public key (full 33 bytes, not hashed, so ignore references to "PKH") + tradeData.creatorForeignPKH = new byte[33]; + dataByteBuffer.get(tradeData.creatorForeignPKH); + dataByteBuffer.position(dataByteBuffer.position() + 40 - tradeData.creatorForeignPKH.length); // skip to 40 bytes + + // We don't use secret-B + tradeData.hashOfSecretB = null; + + // Redeem payout + tradeData.qortAmount = dataByteBuffer.getLong(); + + // Expected ARRR amount + tradeData.expectedForeignAmount = dataByteBuffer.getLong(); + + // Trade timeout + tradeData.tradeTimeout = (int) dataByteBuffer.getLong(); + + // Skip MESSAGE transaction type + dataByteBuffer.position(dataByteBuffer.position() + 8); + + // Skip expected 'trade' message length + dataByteBuffer.position(dataByteBuffer.position() + 8); + + // Skip expected 'redeem' message length + dataByteBuffer.position(dataByteBuffer.position() + 8); + + // Skip pointer to creator's address + dataByteBuffer.position(dataByteBuffer.position() + 8); + + // Skip pointer to partner's Qortal trade address + dataByteBuffer.position(dataByteBuffer.position() + 8); + + // Skip pointer to message sender + dataByteBuffer.position(dataByteBuffer.position() + 8); + + // Skip 'trade' message data offset for first 32 bytes of partner's Pirate Chain public key + dataByteBuffer.position(dataByteBuffer.position() + 8); + + // Skip 'trade' message data offset for last 32 byte of partner's Pirate Chain public key + dataByteBuffer.position(dataByteBuffer.position() + 8); + + // Skip pointer to partner's Pirate Chain public key (first 32 bytes) + dataByteBuffer.position(dataByteBuffer.position() + 8); + + // Skip pointer to partner's Pirate Chain public key (last byte) + dataByteBuffer.position(dataByteBuffer.position() + 8); + + // Skip 'trade' message data offset for hash-of-secret-A + dataByteBuffer.position(dataByteBuffer.position() + 8); + + // Skip pointer to hash-of-secret-A + dataByteBuffer.position(dataByteBuffer.position() + 8); + + // Skip 'redeem' message data offset for partner's Qortal receiving address + dataByteBuffer.position(dataByteBuffer.position() + 8); + + // Skip pointer to message data + dataByteBuffer.position(dataByteBuffer.position() + 8); + + // Skip message data length + dataByteBuffer.position(dataByteBuffer.position() + 8); + + // Skip pointer to partner's receiving address + dataByteBuffer.position(dataByteBuffer.position() + 8); + + /* End of constants / begin variables */ + + // Skip AT creator's address + dataByteBuffer.position(dataByteBuffer.position() + 8 * 4); + + // Partner's trade address (if present) + dataByteBuffer.get(addressBytes); + String qortalRecipient = Base58.encode(addressBytes); + dataByteBuffer.position(dataByteBuffer.position() + 32 - addressBytes.length); + + // Potential lockTimeA (if in trade mode) + int lockTimeA = (int) dataByteBuffer.getLong(); + + // AT refund timeout (probably only useful for debugging) + int refundTimeout = (int) dataByteBuffer.getLong(); + + // Trade-mode refund timestamp (AT 'timestamp' converted to Qortal block height) + long tradeRefundTimestamp = dataByteBuffer.getLong(); + + // Skip last transaction timestamp + dataByteBuffer.position(dataByteBuffer.position() + 8); + + // Skip block timestamp + dataByteBuffer.position(dataByteBuffer.position() + 8); + + // Skip transaction type + dataByteBuffer.position(dataByteBuffer.position() + 8); + + // Skip temporary result + dataByteBuffer.position(dataByteBuffer.position() + 8); + + // Skip temporary message sender + dataByteBuffer.position(dataByteBuffer.position() + 8 * 4); + + // Skip message length + dataByteBuffer.position(dataByteBuffer.position() + 8); + + // Skip temporary message data + dataByteBuffer.position(dataByteBuffer.position() + 8 * 4); + + // Potential hash160 of secret A + byte[] hashOfSecretA = new byte[20]; + dataByteBuffer.get(hashOfSecretA); + dataByteBuffer.position(dataByteBuffer.position() + 32 - hashOfSecretA.length); // skip to 32 bytes + + // Potential partner's PirateChain public key + byte[] partnerPirateChainPublicKey = new byte[33]; + dataByteBuffer.get(partnerPirateChainPublicKey); + dataByteBuffer.position(dataByteBuffer.position() + 64 - partnerPirateChainPublicKey.length); // skip to 64 bytes + + // Partner's receiving address (if present) + byte[] partnerReceivingAddress = new byte[25]; + dataByteBuffer.get(partnerReceivingAddress); + dataByteBuffer.position(dataByteBuffer.position() + 32 - partnerReceivingAddress.length); // skip to 32 bytes + + // Trade AT's 'mode' + long modeValue = dataByteBuffer.getLong(); + AcctMode mode = AcctMode.valueOf((int) (modeValue & 0xffL)); + + /* End of variables */ + + if (mode != null && mode != AcctMode.OFFERING) { + tradeData.mode = mode; + tradeData.refundTimeout = refundTimeout; + tradeData.tradeRefundHeight = new Timestamp(tradeRefundTimestamp).blockHeight; + tradeData.qortalPartnerAddress = qortalRecipient; + tradeData.hashOfSecretA = hashOfSecretA; + tradeData.partnerForeignPKH = partnerPirateChainPublicKey; // Not hashed + tradeData.lockTimeA = lockTimeA; + + if (mode == AcctMode.REDEEMED) + tradeData.qortalPartnerReceivingAddress = Base58.encode(partnerReceivingAddress); + } else { + tradeData.mode = AcctMode.OFFERING; + } + + tradeData.duplicateDeprecated(); + + return tradeData; + } + + /** Returns 'offer' MESSAGE payload for trade partner to send to AT creator's trade address. */ + public static byte[] buildOfferMessage(byte[] partnerBitcoinPublicKey, byte[] hashOfSecretA, int lockTimeA) { + byte[] lockTimeABytes = BitTwiddling.toBEByteArray((long) lockTimeA); + return Bytes.concat(partnerBitcoinPublicKey, hashOfSecretA, lockTimeABytes); + } + + /** Returns info extracted from 'offer' MESSAGE payload sent by trade partner to AT creator's trade address, or null if not valid. */ + public static OfferMessageData extractOfferMessageData(byte[] messageData) { + if (messageData == null || messageData.length != OFFER_MESSAGE_LENGTH) + return null; + + OfferMessageData offerMessageData = new OfferMessageData(); + offerMessageData.partnerPirateChainPublicKey = Arrays.copyOfRange(messageData, 0, 33); + offerMessageData.hashOfSecretA = Arrays.copyOfRange(messageData, 33, 53); + offerMessageData.lockTimeA = BitTwiddling.longFromBEBytes(messageData, 53); + + return offerMessageData; + } + + /** Returns 'trade' MESSAGE payload for AT creator to send to AT. */ + public static byte[] buildTradeMessage(String partnerQortalTradeAddress, byte[] partnerBitcoinPublicKey, byte[] hashOfSecretA, int lockTimeA, int refundTimeout) { + byte[] data = new byte[TRADE_MESSAGE_LENGTH]; + byte[] partnerQortalAddressBytes = Base58.decode(partnerQortalTradeAddress); + byte[] lockTimeABytes = BitTwiddling.toBEByteArray((long) lockTimeA); + byte[] refundTimeoutBytes = BitTwiddling.toBEByteArray((long) refundTimeout); + + System.arraycopy(partnerQortalAddressBytes, 0, data, 0, partnerQortalAddressBytes.length); + System.arraycopy(partnerBitcoinPublicKey, 0, data, 32, partnerBitcoinPublicKey.length); + System.arraycopy(refundTimeoutBytes, 0, data, 72, refundTimeoutBytes.length); + System.arraycopy(hashOfSecretA, 0, data, 80, hashOfSecretA.length); + System.arraycopy(lockTimeABytes, 0, data, 104, lockTimeABytes.length); + + return data; + } + + /** Returns 'cancel' MESSAGE payload for AT creator to cancel trade AT. */ + @Override + public byte[] buildCancelMessage(String creatorQortalAddress) { + byte[] data = new byte[CANCEL_MESSAGE_LENGTH]; + byte[] creatorQortalAddressBytes = Base58.decode(creatorQortalAddress); + + System.arraycopy(creatorQortalAddressBytes, 0, data, 0, creatorQortalAddressBytes.length); + + return data; + } + + /** Returns 'redeem' MESSAGE payload for trade partner to send to AT. */ + public static byte[] buildRedeemMessage(byte[] secretA, String qortalReceivingAddress) { + byte[] data = new byte[REDEEM_MESSAGE_LENGTH]; + byte[] qortalReceivingAddressBytes = Base58.decode(qortalReceivingAddress); + + System.arraycopy(secretA, 0, data, 0, secretA.length); + System.arraycopy(qortalReceivingAddressBytes, 0, data, 32, qortalReceivingAddressBytes.length); + + return data; + } + + /** Returns refund timeout (minutes) based on trade partner's 'offer' MESSAGE timestamp and P2SH-A locktime. */ + public static int calcRefundTimeout(long offerMessageTimestamp, int lockTimeA) { + // refund should be triggered halfway between offerMessageTimestamp and lockTimeA + return (int) ((lockTimeA - (offerMessageTimestamp / 1000L)) / 2L / 60L); + } + + @Override + public byte[] findSecretA(Repository repository, CrossChainTradeData crossChainTradeData) throws DataException { + String atAddress = crossChainTradeData.qortalAtAddress; + String redeemerAddress = crossChainTradeData.qortalPartnerAddress; + + // We don't have partner's public key so we check every message to AT + List messageTransactionsData = repository.getMessageRepository().getMessagesByParticipants(null, atAddress, null, null, null); + if (messageTransactionsData == null) + return null; + + // Find 'redeem' message + for (MessageTransactionData messageTransactionData : messageTransactionsData) { + // Check message payload type/encryption + if (messageTransactionData.isText() || messageTransactionData.isEncrypted()) + continue; + + // Check message payload size + byte[] messageData = messageTransactionData.getData(); + if (messageData.length != REDEEM_MESSAGE_LENGTH) + // Wrong payload length + continue; + + // Check sender + if (!Crypto.toAddress(messageTransactionData.getSenderPublicKey()).equals(redeemerAddress)) + // Wrong sender; + continue; + + // Extract secretA + byte[] secretA = new byte[32]; + System.arraycopy(messageData, 0, secretA, 0, secretA.length); + + byte[] hashOfSecretA = Crypto.hash160(secretA); + if (!Arrays.equals(hashOfSecretA, crossChainTradeData.hashOfSecretA)) + continue; + + return secretA; + } + + return null; + } + +} diff --git a/src/main/java/org/qortal/crosschain/PirateChainHTLC.java b/src/main/java/org/qortal/crosschain/PirateChainHTLC.java new file mode 100644 index 00000000..f28897dc --- /dev/null +++ b/src/main/java/org/qortal/crosschain/PirateChainHTLC.java @@ -0,0 +1,412 @@ +package org.qortal.crosschain; + +import com.google.common.hash.HashCode; +import com.google.common.primitives.Bytes; +import org.bitcoinj.core.*; +import org.bitcoinj.core.Transaction.SigHash; +import org.bitcoinj.crypto.TransactionSignature; +import org.bitcoinj.script.Script; +import org.bitcoinj.script.ScriptBuilder; +import org.bitcoinj.script.ScriptChunk; +import org.bitcoinj.script.ScriptOpCodes; +import org.qortal.crypto.Crypto; +import org.qortal.utils.Base58; +import org.qortal.utils.BitTwiddling; + +import java.util.*; +import java.util.function.Function; + +public class PirateChainHTLC { + + public enum Status { + UNFUNDED, FUNDING_IN_PROGRESS, FUNDED, REDEEM_IN_PROGRESS, REDEEMED, REFUND_IN_PROGRESS, REFUNDED + } + + public static final int SECRET_LENGTH = 32; + public static final int MIN_LOCKTIME = 1500000000; + + public static final long NO_LOCKTIME_NO_RBF_SEQUENCE = 0xFFFFFFFFL; + public static final long LOCKTIME_NO_RBF_SEQUENCE = NO_LOCKTIME_NO_RBF_SEQUENCE - 1; + + // Assuming node's trade-bot has no more than 100 entries? + private static final int MAX_CACHE_ENTRIES = 100; + + // Max time-to-live for cache entries (milliseconds) + private static final long CACHE_TIMEOUT = 30_000L; + + @SuppressWarnings("serial") + private static final Map SECRET_CACHE = new LinkedHashMap<>(MAX_CACHE_ENTRIES + 1, 0.75F, true) { + // This method is called just after a new entry has been added + @Override + public boolean removeEldestEntry(Map.Entry eldest) { + return size() > MAX_CACHE_ENTRIES; + } + }; + private static final byte[] NO_SECRET_CACHE_ENTRY = new byte[0]; + + @SuppressWarnings("serial") + private static final Map STATUS_CACHE = new LinkedHashMap<>(MAX_CACHE_ENTRIES + 1, 0.75F, true) { + // This method is called just after a new entry has been added + @Override + public boolean removeEldestEntry(Map.Entry eldest) { + return size() > MAX_CACHE_ENTRIES; + } + }; + + /* + * OP_RETURN + OP_PUSHDATA1 + bytes (not part of actual redeem script - used for "push only" secondary output when funding P2SH) + * + * OP_IF (if top stack value isn't false) (true=refund; false=redeem) (boolean is then removed from stack) + * + * OP_CHECKLOCKTIMEVERIFY (if stack locktime greater than transaction's lock time - i.e. refunding but too soon - then fail validation) + * OP_DROP (remove locktime from top of stack) + * + * OP_CHECKSIG (check signature and public key are correct; returns 1 or 0) + * OP_ELSE (if top stack value was false, i.e. attempting to redeem) + * OP_SIZE (push length of top item - the secret - to the top of the stack) + * 32 + * OP_EQUALVERIFY (unhashed secret must be 32 bytes in length) + * OP_HASH160 (hash the secret) + * + * OP_EQUALVERIFY (ensure hash of supplied secret matches intended secret hash; transaction invalid if no match) + * + * OP_CHECKSIG (check signature and public key are correct; returns 1 or 0) + * OP_ENDIF + */ + + private static final byte[] pushOnlyPrefix = HashCode.fromString("6a4c").asBytes(); // OP_RETURN + push(redeem script) + private static final byte[] redeemScript1 = HashCode.fromString("6304").asBytes(); // OP_IF push(4 bytes locktime) + private static final byte[] redeemScript2 = HashCode.fromString("b17521").asBytes(); // OP_CHECKLOCKTIMEVERIFY OP_DROP push(33 bytes refund pubkey) + private static final byte[] redeemScript3 = HashCode.fromString("ac6782012088a914").asBytes(); // OP_CHECKSIG OP_ELSE OP_SIZE push(0x20) OP_EQUALVERIFY OP_HASH160 push(20 bytes hash of secret) + private static final byte[] redeemScript4 = HashCode.fromString("8821").asBytes(); // OP_EQUALVERIFY push(33 bytes redeem pubkey) + private static final byte[] redeemScript5 = HashCode.fromString("ac68").asBytes(); // OP_CHECKSIG OP_ENDIF + + /** + * Returns redeemScript used for cross-chain trading. + *

+ * See comments in {@link PirateChainHTLC} for more details. + * + * @param refunderPubKey 33-byte P2SH funder's public key, for refunding purposes + * @param lockTime seconds-since-epoch threshold, after which P2SH funder can claim refund + * @param redeemerPubKey 33-byte P2SH redeemer's public key + * @param hashOfSecret 20-byte HASH160 of secret, used by P2SH redeemer to claim funds + */ + public static byte[] buildScript(byte[] refunderPubKey, int lockTime, byte[] redeemerPubKey, byte[] hashOfSecret) { + return Bytes.concat(redeemScript1, BitTwiddling.toLEByteArray((int) (lockTime & 0xffffffffL)), redeemScript2, + refunderPubKey, redeemScript3, hashOfSecret, redeemScript4, redeemerPubKey, redeemScript5); + } + + /** + * Alternative to buildScript() above, this time with a prefix suitable for adding the redeem script + * to a "push only" output (via OP_RETURN followed by OP_PUSHDATA1) + * + * @param refunderPubKey 33-byte P2SH funder's public key, for refunding purposes + * @param lockTime seconds-since-epoch threshold, after which P2SH funder can claim refund + * @param redeemerPubKey 33-byte P2SH redeemer's public key + * @param hashOfSecret 20-byte HASH160 of secret, used by P2SH redeemer to claim funds + * @return + */ + public static byte[] buildScriptWithPrefix(byte[] refunderPubKey, int lockTime, byte[] redeemerPubKey, byte[] hashOfSecret) { + byte[] redeemScript = buildScript(refunderPubKey, lockTime, redeemerPubKey, hashOfSecret); + int size = redeemScript.length; + String sizeHex = Integer.toHexString(size & 0xFF); + return Bytes.concat(pushOnlyPrefix, HashCode.fromString(sizeHex).asBytes(), redeemScript); + } + + /** + * Returns 'secret', if any, given HTLC's P2SH address. + *

+ * @throws ForeignBlockchainException + */ + public static byte[] findHtlcSecret(Bitcoiny bitcoiny, String p2shAddress) throws ForeignBlockchainException { + NetworkParameters params = bitcoiny.getNetworkParameters(); + String compoundKey = String.format("%s-%s-%d", params.getId(), p2shAddress, System.currentTimeMillis() / CACHE_TIMEOUT); + + byte[] secret = SECRET_CACHE.getOrDefault(compoundKey, NO_SECRET_CACHE_ENTRY); + if (secret != NO_SECRET_CACHE_ENTRY) + return secret; + + List rawTransactions = bitcoiny.getAddressTransactions(p2shAddress); + + for (byte[] rawTransaction : rawTransactions) { + Transaction transaction = new Transaction(params, rawTransaction); + + // Cycle through inputs, looking for one that spends our HTLC + for (TransactionInput input : transaction.getInputs()) { + Script scriptSig = input.getScriptSig(); + List scriptChunks = scriptSig.getChunks(); + + // Expected number of script chunks for redeem. Refund might not have the same number. + int expectedChunkCount = 1 /*secret*/ + 1 /*sig*/ + 1 /*pubkey*/ + 1 /*redeemScript*/; + if (scriptChunks.size() != expectedChunkCount) + continue; + + // We're expecting last chunk to contain the actual redeemScript + ScriptChunk lastChunk = scriptChunks.get(scriptChunks.size() - 1); + byte[] redeemScriptBytes = lastChunk.data; + + // If non-push scripts, redeemScript will be null + if (redeemScriptBytes == null) + continue; + + byte[] redeemScriptHash = Crypto.hash160(redeemScriptBytes); + Address inputAddress = LegacyAddress.fromScriptHash(params, redeemScriptHash); + + if (!inputAddress.toString().equals(p2shAddress)) + // Input isn't spending our HTLC + continue; + + secret = scriptChunks.get(0).data; + if (secret.length != PirateChainHTLC.SECRET_LENGTH) + continue; + + // Cache secret for a while + SECRET_CACHE.put(compoundKey, secret); + + return secret; + } + } + + // Cache negative result + SECRET_CACHE.put(compoundKey, null); + + return null; + } + + /** + * Returns a string containing the txid of the transaction that funded supplied p2shAddress + * We have to do this in a bit of a roundabout way due to the Pirate Light Client server omitting + * transaction hashes from the raw transaction data. + *

+ * @throws ForeignBlockchainException if error occurs + */ + public static String getFundingTxid(BitcoinyBlockchainProvider blockchain, String p2shAddress) throws ForeignBlockchainException { + byte[] ourScriptPubKey = addressToScriptPubKey(p2shAddress); + // HASH160(redeem script) for this p2shAddress + byte[] ourRedeemScriptHash = addressToRedeemScriptHash(p2shAddress); + + + // Firstly look for an unspent output + + // Note: we can't include unconfirmed transactions here because the Pirate light wallet server requires a block range + List unspentOutputs = blockchain.getUnspentOutputs(p2shAddress, false); + for (UnspentOutput unspentOutput : unspentOutputs) { + + if (!Arrays.equals(ourScriptPubKey, unspentOutput.script)) { + continue; + } + + return HashCode.fromBytes(unspentOutput.hash).toString(); + } + + + // No valid unspent outputs, so must be already spent... + + // Note: we can't include unconfirmed transactions here because the Pirate light wallet server requires a block range + List transactions = blockchain.getAddressBitcoinyTransactions(p2shAddress, BitcoinyBlockchainProvider.EXCLUDE_UNCONFIRMED); + + // Sort by confirmed first, followed by ascending height + transactions.sort(BitcoinyTransaction.CONFIRMED_FIRST.thenComparing(BitcoinyTransaction::getHeight)); + + for (BitcoinyTransaction bitcoinyTransaction : transactions) { + + // Acceptable funding is one transaction output, so we're expecting only one input + if (bitcoinyTransaction.inputs.size() != 1) + // Wrong number of inputs + continue; + + String scriptSig = bitcoinyTransaction.inputs.get(0).scriptSig; + + List scriptSigChunks = extractScriptSigChunks(HashCode.fromString(scriptSig).asBytes()); + if (scriptSigChunks.size() < 3 || scriptSigChunks.size() > 4) + // Not valid chunks for our form of HTLC + continue; + + // Last chunk is redeem script + byte[] redeemScriptBytes = scriptSigChunks.get(scriptSigChunks.size() - 1); + byte[] redeemScriptHash = Crypto.hash160(redeemScriptBytes); + if (!Arrays.equals(redeemScriptHash, ourRedeemScriptHash)) + // Not spending our specific HTLC redeem script + continue; + + return bitcoinyTransaction.inputs.get(0).outputTxHash; + + } + + return null; + } + + /** + * Returns a string containing the unspent txid of the transaction that funded supplied p2shAddress + * and is at least the value specified in minimumAmount + *

+ * @throws ForeignBlockchainException if error occurs + */ + public static String getUnspentFundingTxid(BitcoinyBlockchainProvider blockchain, String p2shAddress, long minimumAmount) throws ForeignBlockchainException { + byte[] ourScriptPubKey = addressToScriptPubKey(p2shAddress); + + // Note: we can't include unconfirmed transactions here because the Pirate light wallet server requires a block range + List unspentOutputs = blockchain.getUnspentOutputs(p2shAddress, false); + for (UnspentOutput unspentOutput : unspentOutputs) { + + if (!Arrays.equals(ourScriptPubKey, unspentOutput.script)) { + // Not funding our specific HTLC script hash + continue; + } + + if (unspentOutput.value < minimumAmount) { + // Not funding the required amount + continue; + } + + return HashCode.fromBytes(unspentOutput.hash).toString(); + } + + + // No valid unspent outputs, so must be already spent + return null; + } + + /** + * Returns HTLC status, given P2SH address and expected redeem/refund amount + *

+ * @throws ForeignBlockchainException if error occurs + */ + public static Status determineHtlcStatus(BitcoinyBlockchainProvider blockchain, String p2shAddress, long minimumAmount) throws ForeignBlockchainException { + String compoundKey = String.format("%s-%s-%d", blockchain.getNetId(), p2shAddress, System.currentTimeMillis() / CACHE_TIMEOUT); + + Status cachedStatus = STATUS_CACHE.getOrDefault(compoundKey, null); + if (cachedStatus != null) + return cachedStatus; + + byte[] ourScriptPubKey = addressToScriptPubKey(p2shAddress); + + // Note: we can't include unconfirmed transactions here because the Pirate light wallet server requires a block range + List transactions = blockchain.getAddressBitcoinyTransactions(p2shAddress, BitcoinyBlockchainProvider.EXCLUDE_UNCONFIRMED); + + // Sort by confirmed first, followed by ascending height + transactions.sort(BitcoinyTransaction.CONFIRMED_FIRST.thenComparing(BitcoinyTransaction::getHeight)); + + // Transaction cache + //Map transactionsByHash = new HashMap<>(); + // HASH160(redeem script) for this p2shAddress + byte[] ourRedeemScriptHash = addressToRedeemScriptHash(p2shAddress); + + // Check for spends first, caching full transaction info as we progress just in case we don't return in this loop + for (BitcoinyTransaction bitcoinyTransaction : transactions) { + + // Cache for possible later reuse + // transactionsByHash.put(transactionInfo.txHash, bitcoinyTransaction); + + // Acceptable funding is one transaction output, so we're expecting only one input + if (bitcoinyTransaction.inputs.size() != 1) + // Wrong number of inputs + continue; + + String scriptSig = bitcoinyTransaction.inputs.get(0).scriptSig; + + List scriptSigChunks = extractScriptSigChunks(HashCode.fromString(scriptSig).asBytes()); + if (scriptSigChunks.size() < 3 || scriptSigChunks.size() > 4) + // Not valid chunks for our form of HTLC + continue; + + // Last chunk is redeem script + byte[] redeemScriptBytes = scriptSigChunks.get(scriptSigChunks.size() - 1); + byte[] redeemScriptHash = Crypto.hash160(redeemScriptBytes); + if (!Arrays.equals(redeemScriptHash, ourRedeemScriptHash)) + // Not spending our specific HTLC redeem script + continue; + + if (scriptSigChunks.size() == 4) + // If we have 4 chunks, then secret is present, hence redeem + cachedStatus = bitcoinyTransaction.height == 0 ? Status.REDEEM_IN_PROGRESS : Status.REDEEMED; + else + cachedStatus = bitcoinyTransaction.height == 0 ? Status.REFUND_IN_PROGRESS : Status.REFUNDED; + + STATUS_CACHE.put(compoundKey, cachedStatus); + return cachedStatus; + } + + String ourScriptPubKeyHex = HashCode.fromBytes(ourScriptPubKey).toString(); + + // Check for funding + for (BitcoinyTransaction bitcoinyTransaction : transactions) { + if (bitcoinyTransaction == null) + // Should be present in map! + throw new ForeignBlockchainException("Cached Bitcoin transaction now missing?"); + + // Check outputs for our specific P2SH + for (BitcoinyTransaction.Output output : bitcoinyTransaction.outputs) { + // Check amount + if (output.value < minimumAmount) + // Output amount too small (not taking fees into account) + continue; + + String scriptPubKeyHex = output.scriptPubKey; + if (!scriptPubKeyHex.equals(ourScriptPubKeyHex)) + // Not funding our specific P2SH + continue; + + cachedStatus = bitcoinyTransaction.height == 0 ? Status.FUNDING_IN_PROGRESS : Status.FUNDED; + STATUS_CACHE.put(compoundKey, cachedStatus); + return cachedStatus; + } + } + + cachedStatus = Status.UNFUNDED; + STATUS_CACHE.put(compoundKey, cachedStatus); + return cachedStatus; + } + + private static List extractScriptSigChunks(byte[] scriptSigBytes) { + List chunks = new ArrayList<>(); + + int offset = 0; + int previousOffset = 0; + while (offset < scriptSigBytes.length) { + byte pushOp = scriptSigBytes[offset++]; + + if (pushOp < 0 || pushOp > 0x4c) + // Unacceptable OP + return Collections.emptyList(); + + // Special treatment for OP_PUSHDATA1 + if (pushOp == 0x4c) { + if (offset >= scriptSigBytes.length) + // Run out of scriptSig bytes? + return Collections.emptyList(); + + pushOp = scriptSigBytes[offset++]; + } + + previousOffset = offset; + offset += Byte.toUnsignedInt(pushOp); + + byte[] chunk = Arrays.copyOfRange(scriptSigBytes, previousOffset, offset); + chunks.add(chunk); + } + + return chunks; + } + + private static byte[] addressToScriptPubKey(String p2shAddress) { + // We want the HASH160 part of the P2SH address + byte[] p2shAddressBytes = Base58.decode(p2shAddress); + + byte[] scriptPubKey = new byte[1 + 1 + 20 + 1]; + scriptPubKey[0x00] = (byte) 0xa9; /* OP_HASH160 */ + scriptPubKey[0x01] = (byte) 0x14; /* PUSH 0x14 bytes */ + System.arraycopy(p2shAddressBytes, 1, scriptPubKey, 2, 0x14); + scriptPubKey[0x16] = (byte) 0x87; /* OP_EQUAL */ + + return scriptPubKey; + } + + private static byte[] addressToRedeemScriptHash(String p2shAddress) { + // We want the HASH160 part of the P2SH address + byte[] p2shAddressBytes = Base58.decode(p2shAddress); + + return Arrays.copyOfRange(p2shAddressBytes, 1, 1 + 20); + } + +} diff --git a/src/main/java/org/qortal/crosschain/PirateLightClient.java b/src/main/java/org/qortal/crosschain/PirateLightClient.java new file mode 100644 index 00000000..63bcd5fa --- /dev/null +++ b/src/main/java/org/qortal/crosschain/PirateLightClient.java @@ -0,0 +1,649 @@ +package org.qortal.crosschain; + +import cash.z.wallet.sdk.rpc.CompactFormats.*; +import cash.z.wallet.sdk.rpc.CompactTxStreamerGrpc; +import cash.z.wallet.sdk.rpc.Service; +import cash.z.wallet.sdk.rpc.Service.*; +import com.google.common.hash.HashCode; +import com.google.protobuf.ByteString; +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.qortal.settings.Settings; +import org.qortal.transform.TransformationException; + +import java.math.BigDecimal; +import java.util.*; +import java.util.concurrent.TimeUnit; + +/** Pirate Chain network support for querying Bitcoiny-related info like block headers, transaction outputs, etc. */ +public class PirateLightClient extends BitcoinyBlockchainProvider { + + private static final Logger LOGGER = LogManager.getLogger(PirateLightClient.class); + private static final Random RANDOM = new Random(); + + private static final int RESPONSE_TIME_READINGS = 5; + private static final long MAX_AVG_RESPONSE_TIME = 500L; // ms + + public static class Server { + String hostname; + + public enum ConnectionType { TCP, SSL } + ConnectionType connectionType; + + int port; + private List responseTimes = new ArrayList<>(); + + public Server(String hostname, ConnectionType connectionType, int port) { + this.hostname = hostname; + this.connectionType = connectionType; + this.port = port; + } + + public void addResponseTime(long responseTime) { + while (this.responseTimes.size() > RESPONSE_TIME_READINGS) { + this.responseTimes.remove(0); + } + this.responseTimes.add(responseTime); + } + + public long averageResponseTime() { + if (this.responseTimes.size() < RESPONSE_TIME_READINGS) { + // Not enough readings yet + return 0L; + } + OptionalDouble average = this.responseTimes.stream().mapToDouble(a -> a).average(); + if (average.isPresent()) { + return Double.valueOf(average.getAsDouble()).longValue(); + } + return 0L; + } + + @Override + public boolean equals(Object other) { + if (other == this) + return true; + + if (!(other instanceof Server)) + return false; + + Server otherServer = (Server) other; + + return this.connectionType == otherServer.connectionType + && this.port == otherServer.port + && this.hostname.equals(otherServer.hostname); + } + + @Override + public int hashCode() { + return this.hostname.hashCode() ^ this.port; + } + + @Override + public String toString() { + return String.format("%s:%s:%d", this.connectionType.name(), this.hostname, this.port); + } + } + private Set servers = new HashSet<>(); + private List remainingServers = new ArrayList<>(); + private Set uselessServers = Collections.synchronizedSet(new HashSet<>()); + + private final String netId; + private final String expectedGenesisHash; + private final Map defaultPorts = new EnumMap<>(Server.ConnectionType.class); + private Bitcoiny blockchain; + + private final Object serverLock = new Object(); + private Server currentServer; + private ManagedChannel channel; + private int nextId = 1; + + private static final int TX_CACHE_SIZE = 1000; + @SuppressWarnings("serial") + private final Map transactionCache = Collections.synchronizedMap(new LinkedHashMap<>(TX_CACHE_SIZE + 1, 0.75F, true) { + // This method is called just after a new entry has been added + @Override + public boolean removeEldestEntry(Map.Entry eldest) { + return size() > TX_CACHE_SIZE; + } + }); + + // Constructors + + public PirateLightClient(String netId, String genesisHash, Collection initialServerList, Map defaultPorts) { + this.netId = netId; + this.expectedGenesisHash = genesisHash; + this.servers.addAll(initialServerList); + this.defaultPorts.putAll(defaultPorts); + } + + // Methods for use by other classes + + @Override + public void setBlockchain(Bitcoiny blockchain) { + this.blockchain = blockchain; + } + + @Override + public String getNetId() { + return this.netId; + } + + /** + * Returns current blockchain height. + *

+ * @throws ForeignBlockchainException if error occurs + */ + @Override + public int getCurrentHeight() throws ForeignBlockchainException { + BlockID latestBlock = this.getCompactTxStreamerStub().getLatestBlock(null); + + if (!(latestBlock instanceof BlockID)) + throw new ForeignBlockchainException.NetworkException("Unexpected output from Pirate Chain getLatestBlock gRPC"); + + return (int)latestBlock.getHeight(); + } + + /** + * Returns list of compact blocks, starting from startHeight inclusive. + *

+ * @throws ForeignBlockchainException if error occurs + * @return + */ + @Override + public List getCompactBlocks(int startHeight, int count) throws ForeignBlockchainException { + BlockID startBlock = BlockID.newBuilder().setHeight(startHeight).build(); + BlockID endBlock = BlockID.newBuilder().setHeight(startHeight + count - 1).build(); + BlockRange range = BlockRange.newBuilder().setStart(startBlock).setEnd(endBlock).build(); + + Iterator blocksIterator = this.getCompactTxStreamerStub().getBlockRange(range); + + // Map from Iterator to List + List blocks = new ArrayList<>(); + blocksIterator.forEachRemaining(blocks::add); + + return blocks; + } + + /** + * Returns list of raw block headers, starting from startHeight inclusive. + *

+ * @throws ForeignBlockchainException if error occurs + */ + @Override + public List getRawBlockHeaders(int startHeight, int count) throws ForeignBlockchainException { + BlockID startBlock = BlockID.newBuilder().setHeight(startHeight).build(); + BlockID endBlock = BlockID.newBuilder().setHeight(startHeight + count - 1).build(); + BlockRange range = BlockRange.newBuilder().setStart(startBlock).setEnd(endBlock).build(); + + Iterator blocks = this.getCompactTxStreamerStub().getBlockRange(range); + + List rawBlockHeaders = new ArrayList<>(); + + while (blocks.hasNext()) { + CompactBlock block = blocks.next(); + + if (block.getHeader() == null) { + throw new ForeignBlockchainException.NetworkException("Unexpected output from Pirate Chain getBlockRange gRPC"); + } + + rawBlockHeaders.add(block.getHeader().toByteArray()); + } + + return rawBlockHeaders; + } + + /** + * Returns list of raw block timestamps, starting from startHeight inclusive. + *

+ * @throws ForeignBlockchainException if error occurs + */ + @Override + public List getBlockTimestamps(int startHeight, int count) throws ForeignBlockchainException { + BlockID startBlock = BlockID.newBuilder().setHeight(startHeight).build(); + BlockID endBlock = BlockID.newBuilder().setHeight(startHeight + count - 1).build(); + BlockRange range = BlockRange.newBuilder().setStart(startBlock).setEnd(endBlock).build(); + + Iterator blocks = this.getCompactTxStreamerStub().getBlockRange(range); + + List rawBlockTimestamps = new ArrayList<>(); + + while (blocks.hasNext()) { + CompactBlock block = blocks.next(); + + if (block.getTime() <= 0) { + throw new ForeignBlockchainException.NetworkException("Unexpected output from Pirate Chain getBlockRange gRPC"); + } + + rawBlockTimestamps.add(Long.valueOf(block.getTime())); + } + + return rawBlockTimestamps; + } + + /** + * Returns confirmed balance, based on passed payment script. + *

+ * @return confirmed balance, or zero if script unknown + * @throws ForeignBlockchainException if there was an error + */ + @Override + public long getConfirmedBalance(byte[] script) throws ForeignBlockchainException { + throw new ForeignBlockchainException("getConfirmedBalance not yet implemented for Pirate Chain"); + } + + /** + * Returns confirmed balance, based on passed base58 encoded address. + *

+ * @return confirmed balance, or zero if address unknown + * @throws ForeignBlockchainException if there was an error + */ + @Override + public long getConfirmedAddressBalance(String base58Address) throws ForeignBlockchainException { + AddressList addressList = AddressList.newBuilder().addAddresses(base58Address).build(); + Balance balance = this.getCompactTxStreamerStub().getTaddressBalance(addressList); + + if (!(balance instanceof Balance)) + throw new ForeignBlockchainException.NetworkException("Unexpected output from Pirate Chain getConfirmedAddressBalance gRPC"); + + return balance.getValueZat(); + } + + /** + * Returns list of unspent outputs pertaining to passed address. + *

+ * @return list of unspent outputs, or empty list if address unknown + * @throws ForeignBlockchainException if there was an error. + */ + @Override + public List getUnspentOutputs(String address, boolean includeUnconfirmed) throws ForeignBlockchainException { + GetAddressUtxosArg getAddressUtxosArg = GetAddressUtxosArg.newBuilder().addAddresses(address).build(); + GetAddressUtxosReplyList replyList = this.getCompactTxStreamerStub().getAddressUtxos(getAddressUtxosArg); + + if (!(replyList instanceof GetAddressUtxosReplyList)) + throw new ForeignBlockchainException.NetworkException("Unexpected output from Pirate Chain getUnspentOutputs gRPC"); + + List unspentList = replyList.getAddressUtxosList(); + if (unspentList == null) + throw new ForeignBlockchainException.NetworkException("Unexpected output from Pirate Chain getUnspentOutputs gRPC"); + + List unspentOutputs = new ArrayList<>(); + for (GetAddressUtxosReply unspent : unspentList) { + + int height = (int)unspent.getHeight(); + // We only want unspent outputs from confirmed transactions (and definitely not mempool duplicates with height 0) + if (!includeUnconfirmed && height <= 0) + continue; + + byte[] txHash = unspent.getTxid().toByteArray(); + int outputIndex = unspent.getIndex(); + long value = unspent.getValueZat(); + byte[] script = unspent.getScript().toByteArray(); + String addressRes = unspent.getAddress(); + + unspentOutputs.add(new UnspentOutput(txHash, outputIndex, height, value, script, addressRes)); + } + + return unspentOutputs; + } + + /** + * Returns list of unspent outputs pertaining to passed payment script. + *

+ * @return list of unspent outputs, or empty list if script unknown + * @throws ForeignBlockchainException if there was an error. + */ + @Override + public List getUnspentOutputs(byte[] script, boolean includeUnconfirmed) throws ForeignBlockchainException { + String address = this.blockchain.deriveP2shAddress(script); + return this.getUnspentOutputs(address, includeUnconfirmed); + } + + /** + * Returns raw transaction for passed transaction hash. + *

+ * NOTE: Do not mutate returned byte[]! + * + * @throws ForeignBlockchainException.NotFoundException if transaction not found + * @throws ForeignBlockchainException if error occurs + */ + @Override + public byte[] getRawTransaction(String txHash) throws ForeignBlockchainException { + return getRawTransaction(HashCode.fromString(txHash).asBytes()); + } + + /** + * Returns raw transaction for passed transaction hash. + *

+ * NOTE: Do not mutate returned byte[]! + * + * @throws ForeignBlockchainException.NotFoundException if transaction not found + * @throws ForeignBlockchainException if error occurs + */ + @Override + public byte[] getRawTransaction(byte[] txHash) throws ForeignBlockchainException { + ByteString byteString = ByteString.copyFrom(txHash); + TxFilter txFilter = TxFilter.newBuilder().setHash(byteString).build(); + RawTransaction rawTransaction = this.getCompactTxStreamerStub().getTransaction(txFilter); + + if (!(rawTransaction instanceof RawTransaction)) + throw new ForeignBlockchainException.NetworkException("Unexpected output from Pirate Chain getTransaction gRPC"); + + return rawTransaction.getData().toByteArray(); + } + + /** + * Returns transaction info for passed transaction hash. + *

+ * @throws ForeignBlockchainException.NotFoundException if transaction not found + * @throws ForeignBlockchainException if error occurs + */ + @Override + public BitcoinyTransaction getTransaction(String txHash) throws ForeignBlockchainException { + // Check cache first + BitcoinyTransaction transaction = transactionCache.get(txHash); + if (transaction != null) + return transaction; + + ByteString byteString = ByteString.copyFrom(HashCode.fromString(txHash).asBytes()); + TxFilter txFilter = TxFilter.newBuilder().setHash(byteString).build(); + RawTransaction rawTransaction = this.getCompactTxStreamerStub().getTransaction(txFilter); + + if (!(rawTransaction instanceof RawTransaction)) + throw new ForeignBlockchainException.NetworkException("Unexpected output from Pirate Chain getTransaction gRPC"); + + byte[] transactionData = rawTransaction.getData().toByteArray(); + String transactionDataString = HashCode.fromBytes(transactionData).toString(); + + JSONParser parser = new JSONParser(); + JSONObject transactionJson; + try { + transactionJson = (JSONObject) parser.parse(transactionDataString); + } catch (ParseException e) { + throw new ForeignBlockchainException.NetworkException("Expected JSON string from Pirate Chain getTransaction gRPC"); + } + + Object inputsObj = transactionJson.get("vin"); + if (!(inputsObj instanceof JSONArray)) + throw new ForeignBlockchainException.NetworkException("Expected JSONArray for 'vin' from Pirate Chain getTransaction gRPC"); + + Object outputsObj = transactionJson.get("vout"); + if (!(outputsObj instanceof JSONArray)) + throw new ForeignBlockchainException.NetworkException("Expected JSONArray for 'vout' from Pirate Chain getTransaction gRPC"); + + try { + int size = ((Long) transactionJson.get("size")).intValue(); + int locktime = ((Long) transactionJson.get("locktime")).intValue(); + + // Timestamp might not be present, e.g. for unconfirmed transaction + Object timeObj = transactionJson.get("time"); + Integer timestamp = timeObj != null + ? ((Long) timeObj).intValue() + : null; + + List inputs = new ArrayList<>(); + for (Object inputObj : (JSONArray) inputsObj) { + JSONObject inputJson = (JSONObject) inputObj; + + String scriptSig = (String) ((JSONObject) inputJson.get("scriptSig")).get("hex"); + int sequence = ((Long) inputJson.get("sequence")).intValue(); + String outputTxHash = (String) inputJson.get("txid"); + int outputVout = ((Long) inputJson.get("vout")).intValue(); + + inputs.add(new BitcoinyTransaction.Input(scriptSig, sequence, outputTxHash, outputVout)); + } + + List outputs = new ArrayList<>(); + for (Object outputObj : (JSONArray) outputsObj) { + JSONObject outputJson = (JSONObject) outputObj; + + String scriptPubKey = (String) ((JSONObject) outputJson.get("scriptPubKey")).get("hex"); + long value = BigDecimal.valueOf((Double) outputJson.get("value")).setScale(8).unscaledValue().longValue(); + + // address too, if present in the "addresses" array + List addresses = null; + Object addressesObj = ((JSONObject) outputJson.get("scriptPubKey")).get("addresses"); + if (addressesObj instanceof JSONArray) { + addresses = new ArrayList<>(); + for (Object addressObj : (JSONArray) addressesObj) { + addresses.add((String) addressObj); + } + } + + // some peers return a single "address" string + Object addressObj = ((JSONObject) outputJson.get("scriptPubKey")).get("address"); + if (addressObj instanceof String) { + if (addresses == null) { + addresses = new ArrayList<>(); + } + addresses.add((String) addressObj); + } + + // For the purposes of Qortal we require all outputs to contain addresses + // Some servers omit this info, causing problems down the line with balance calculations + // Update: it turns out that they were just using a different key - "address" instead of "addresses" + // The code below can remain in place, just in case a peer returns a missing address in the future + if (addresses == null || addresses.isEmpty()) { + if (this.currentServer != null) { + this.uselessServers.add(this.currentServer); + this.closeServer(this.currentServer); + } + LOGGER.info("No output addresses returned for transaction {}", txHash); + throw new ForeignBlockchainException(String.format("No output addresses returned for transaction %s", txHash)); + } + + outputs.add(new BitcoinyTransaction.Output(scriptPubKey, value, addresses)); + } + + transaction = new BitcoinyTransaction(txHash, size, locktime, timestamp, inputs, outputs); + + // Save into cache + transactionCache.put(txHash, transaction); + + return transaction; + } catch (NullPointerException | ClassCastException e) { + // Unexpected / invalid response from ElectrumX server + } + + throw new ForeignBlockchainException.NetworkException("Unexpected JSON format from Pirate Chain getTransaction gRPC"); + } + + /** + * Returns list of transactions, relating to passed payment script. + *

+ * @return list of related transactions, or empty list if script unknown + * @throws ForeignBlockchainException if error occurs + */ + @Override + public List getAddressTransactions(byte[] script, boolean includeUnconfirmed) throws ForeignBlockchainException { + // FUTURE: implement this if needed. Probably not very useful for private blockchains. + throw new ForeignBlockchainException("getAddressTransactions not yet implemented for Pirate Chain"); + } + + @Override + public List getAddressBitcoinyTransactions(String address, boolean includeUnconfirmed) throws ForeignBlockchainException { + try { + // Firstly we need to get the latest block + int defaultBirthday = Settings.getInstance().getArrrDefaultBirthday(); + BlockID endBlock = this.getCompactTxStreamerStub().getLatestBlock(null); + BlockID startBlock = BlockID.newBuilder().setHeight(defaultBirthday).build(); + BlockRange blockRange = BlockRange.newBuilder().setStart(startBlock).setEnd(endBlock).build(); + + TransparentAddressBlockFilter blockFilter = TransparentAddressBlockFilter.newBuilder() + .setAddress(address) + .setRange(blockRange) + .build(); + Iterator transactionIterator = this.getCompactTxStreamerStub().getTaddressTxids(blockFilter); + + // Map from Iterator to List + List rawTransactions = new ArrayList<>(); + transactionIterator.forEachRemaining(rawTransactions::add); + + List transactions = new ArrayList<>(); + + for (RawTransaction rawTransaction : rawTransactions) { + + Long height = rawTransaction.getHeight(); + if (!includeUnconfirmed && (height == null || height == 0)) + // We only want confirmed transactions + continue; + + byte[] transactionData = rawTransaction.getData().toByteArray(); + String transactionDataHex = HashCode.fromBytes(transactionData).toString(); + BitcoinyTransaction bitcoinyTransaction = PirateChain.deserializeRawTransaction(transactionDataHex); + bitcoinyTransaction.height = height.intValue(); + transactions.add(bitcoinyTransaction); + } + + return transactions; + } + catch (RuntimeException | TransformationException e) { + throw new ForeignBlockchainException(String.format("Unable to get transactions for address %s: %s", address, e.getMessage())); + } + } + + /** + * Broadcasts raw transaction to network. + *

+ * @throws ForeignBlockchainException if error occurs + */ + @Override + public void broadcastTransaction(byte[] transactionBytes) throws ForeignBlockchainException { + ByteString byteString = ByteString.copyFrom(transactionBytes); + RawTransaction rawTransaction = RawTransaction.newBuilder().setData(byteString).build(); + SendResponse sendResponse = this.getCompactTxStreamerStub().sendTransaction(rawTransaction); + + if (!(sendResponse instanceof SendResponse)) + throw new ForeignBlockchainException.NetworkException("Unexpected output from Pirate Chain broadcastTransaction gRPC"); + + if (sendResponse.getErrorCode() != 0) + throw new ForeignBlockchainException.NetworkException(String.format("Unexpected error code from Pirate Chain broadcastTransaction gRPC: %d", sendResponse.getErrorCode())); + } + + // Class-private utility methods + + + /** + * Performs RPC call, with automatic reconnection to different server if needed. + *

+ * @return "result" object from within JSON output + * @throws ForeignBlockchainException if server returns error or something goes wrong + */ + private CompactTxStreamerGrpc.CompactTxStreamerBlockingStub getCompactTxStreamerStub() throws ForeignBlockchainException { + synchronized (this.serverLock) { + if (this.remainingServers.isEmpty()) + this.remainingServers.addAll(this.servers); + + while (haveConnection()) { + // If we have more servers and the last one replied slowly, try another + if (!this.remainingServers.isEmpty()) { + long averageResponseTime = this.currentServer.averageResponseTime(); + if (averageResponseTime > MAX_AVG_RESPONSE_TIME) { + LOGGER.info("Slow average response time {}ms from {} - trying another server...", averageResponseTime, this.currentServer.hostname); + this.closeServer(); + continue; + } + } + + return CompactTxStreamerGrpc.newBlockingStub(this.channel); + +// // Didn't work, try another server... +// this.closeServer(); + } + + // Failed to perform RPC - maybe lack of servers? + LOGGER.info("Error: No connected Pirate Light servers when trying to make RPC call"); + throw new ForeignBlockchainException.NetworkException("No connected Pirate Light servers when trying to make RPC call"); + } + } + + /** Returns true if we have, or create, a connection to an ElectrumX server. */ + private boolean haveConnection() throws ForeignBlockchainException { + if (this.currentServer != null && this.channel != null && !this.channel.isShutdown()) + return true; + + while (!this.remainingServers.isEmpty()) { + Server server = this.remainingServers.remove(RANDOM.nextInt(this.remainingServers.size())); + LOGGER.trace(() -> String.format("Connecting to %s", server)); + + try { + this.channel = ManagedChannelBuilder.forAddress(server.hostname, server.port).build(); + + CompactTxStreamerGrpc.CompactTxStreamerBlockingStub stub = CompactTxStreamerGrpc.newBlockingStub(this.channel); + LightdInfo lightdInfo = stub.getLightdInfo(Empty.newBuilder().build()); + + if (lightdInfo == null || lightdInfo.getBlockHeight() <= 0) + continue; + + // TODO: find a way to verify that the server is using the expected chain + +// if (featuresJson == null || Double.valueOf((String) featuresJson.get("protocol_min")) < MIN_PROTOCOL_VERSION) +// continue; + +// if (this.expectedGenesisHash != null && !((String) featuresJson.get("genesis_hash")).equals(this.expectedGenesisHash)) +// continue; + + LOGGER.debug(() -> String.format("Connected to %s", server)); + this.currentServer = server; + return true; + } catch (Exception e) { + // Didn't work, try another server... + closeServer(); + } + } + + return false; + } + + /** + * Closes connection to server if it is currently connected server. + * @param server + */ + private void closeServer(Server server) { + synchronized (this.serverLock) { + if (this.currentServer == null || !this.currentServer.equals(server) || this.channel == null) { + return; + } + + // Close the gRPC managed-channel if not shut down already. + if (!this.channel.isShutdown()) { + try { + this.channel.shutdown(); + if (!this.channel.awaitTermination(10, TimeUnit.SECONDS)) { + LOGGER.warn("Timed out gracefully shutting down connection: {}. ", this.channel); + } + } catch (Exception e) { + LOGGER.error("Unexpected exception while waiting for channel termination", e); + } + } + + // Forceful shut down if still not terminated. + if (!this.channel.isTerminated()) { + try { + this.channel.shutdownNow(); + if (!this.channel.awaitTermination(15, TimeUnit.SECONDS)) { + LOGGER.warn("Timed out forcefully shutting down connection: {}. ", this.channel); + } + } catch (Exception e) { + LOGGER.error("Unexpected exception while waiting for channel termination", e); + } + } + + this.channel = null; + this.currentServer = null; + } + } + + /** Closes connection to currently connected server (if any). */ + private void closeServer() { + synchronized (this.serverLock) { + this.closeServer(this.currentServer); + } + } + +} diff --git a/src/main/java/org/qortal/crosschain/PirateWallet.java b/src/main/java/org/qortal/crosschain/PirateWallet.java new file mode 100644 index 00000000..6c6ed2a9 --- /dev/null +++ b/src/main/java/org/qortal/crosschain/PirateWallet.java @@ -0,0 +1,409 @@ +package org.qortal.crosschain; + +import com.rust.litewalletjni.LiteWalletJni; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.bouncycastle.util.encoders.Base64; +import org.bouncycastle.util.encoders.DecoderException; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.qortal.controller.PirateChainWalletController; +import org.qortal.crypto.Crypto; +import org.qortal.settings.Settings; +import org.qortal.utils.Base58; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.Arrays; +import java.util.Collection; +import java.util.Objects; +import java.util.Random; + +public class PirateWallet { + + protected static final Logger LOGGER = LogManager.getLogger(PirateWallet.class); + + private byte[] entropyBytes; + private final boolean isNullSeedWallet; + private String seedPhrase; + private boolean ready = false; + + private String params; + private String saplingOutput64; + private String saplingSpend64; + + private final static String COIN_PARAMS_FILENAME = "coinparams.json"; + private final static String SAPLING_OUTPUT_FILENAME = "saplingoutput_base64"; + private final static String SAPLING_SPEND_FILENAME = "saplingspend_base64"; + + public PirateWallet(byte[] entropyBytes, boolean isNullSeedWallet) throws IOException { + this.entropyBytes = entropyBytes; + this.isNullSeedWallet = isNullSeedWallet; + + Path libDirectory = PirateChainWalletController.getRustLibOuterDirectory(); + if (!Files.exists(Paths.get(libDirectory.toString(), COIN_PARAMS_FILENAME))) { + return; + } + + this.params = Files.readString(Paths.get(libDirectory.toString(), COIN_PARAMS_FILENAME)); + this.saplingOutput64 = Files.readString(Paths.get(libDirectory.toString(), SAPLING_OUTPUT_FILENAME)); + this.saplingSpend64 = Files.readString(Paths.get(libDirectory.toString(), SAPLING_SPEND_FILENAME)); + + this.ready = this.initialize(); + } + + private boolean initialize() { + try { + LiteWalletJni.initlogging(); + + if (this.entropyBytes == null) { + return false; + } + + // Pick a random server + PirateLightClient.Server server = this.getRandomServer(); + String serverUri = String.format("https://%s:%d/", server.hostname, server.port); + + // Pirate library uses base64 encoding + String entropy64 = Base64.toBase64String(this.entropyBytes); + + // Derive seed phrase from entropy bytes + String inputSeedResponse = LiteWalletJni.getseedphrasefromentropyb64(entropy64); + JSONObject inputSeedJson = new JSONObject(inputSeedResponse); + String inputSeedPhrase = null; + if (inputSeedJson.has("seedPhrase")) { + inputSeedPhrase = inputSeedJson.getString("seedPhrase"); + } + + String wallet = this.load(); + if (wallet == null) { + // Wallet doesn't exist, so create a new one + + int birthday = Settings.getInstance().getArrrDefaultBirthday(); + if (this.isNullSeedWallet) { + try { + // Attempt to set birthday to the current block for null seed wallets + birthday = PirateChain.getInstance().blockchainProvider.getCurrentHeight(); + } + catch (ForeignBlockchainException e) { + // Use the default height + } + } + + // Initialize new wallet + String birthdayString = String.format("%d", birthday); + String outputSeedResponse = LiteWalletJni.initfromseed(serverUri, this.params, inputSeedPhrase, birthdayString, this.saplingOutput64, this.saplingSpend64); // Thread-safe. + JSONObject outputSeedJson = new JSONObject(outputSeedResponse); + String outputSeedPhrase = null; + if (outputSeedJson.has("seed")) { + outputSeedPhrase = outputSeedJson.getString("seed"); + } + + // Ensure seed phrase in response matches supplied seed phrase + if (inputSeedPhrase == null || !Objects.equals(inputSeedPhrase, outputSeedPhrase)) { + LOGGER.info("Unable to initialize Pirate Chain wallet: seed phrases do not match, or are null"); + return false; + } + + this.seedPhrase = outputSeedPhrase; + + } else { + // Restore existing wallet + String response = LiteWalletJni.initfromb64(serverUri, params, wallet, saplingOutput64, saplingSpend64); + if (response != null && !response.contains("\"initalized\":true")) { + LOGGER.info("Unable to initialize Pirate Chain wallet: {}", response); + return false; + } + this.seedPhrase = inputSeedPhrase; + } + + // Check that we're able to communicate with the library + Integer ourHeight = this.getHeight(); + return (ourHeight != null && ourHeight > 0); + + } catch (IOException | JSONException | UnsatisfiedLinkError e) { + LOGGER.info("Unable to initialize Pirate Chain wallet: {}", e.getMessage()); + } + + return false; + } + + public boolean isReady() { + return this.ready; + } + + public void setReady(boolean ready) { + this.ready = ready; + } + + public boolean entropyBytesEqual(byte[] testEntropyBytes) { + return Arrays.equals(testEntropyBytes, this.entropyBytes); + } + + private void encrypt() { + if (this.isEncrypted()) { + // Nothing to do + return; + } + + String encryptionKey = this.getEncryptionKey(); + if (encryptionKey == null) { + // Can't encrypt without a key + return; + } + + this.doEncrypt(encryptionKey); + } + + private void decrypt() { + if (!this.isEncrypted()) { + // Nothing to do + return; + } + + String encryptionKey = this.getEncryptionKey(); + if (encryptionKey == null) { + // Can't encrypt without a key + return; + } + + this.doDecrypt(encryptionKey); + } + + public void unlock() { + if (!this.isEncrypted()) { + // Nothing to do + return; + } + + String encryptionKey = this.getEncryptionKey(); + if (encryptionKey == null) { + // Can't encrypt without a key + return; + } + + this.doUnlock(encryptionKey); + } + + public boolean save() throws IOException { + if (!isInitialized()) { + LOGGER.info("Error: can't save wallet, because no wallet it initialized"); + return false; + } + if (this.isNullSeedWallet()) { + // Don't save wallets that have a null seed + return false; + } + + // Encrypt first (will do nothing if already encrypted) + this.encrypt(); + + String wallet64 = LiteWalletJni.save(); + byte[] wallet; + try { + wallet = Base64.decode(wallet64); + } + catch (DecoderException e) { + LOGGER.info("Unable to decode wallet"); + return false; + } + if (wallet == null) { + LOGGER.info("Unable to save wallet"); + return false; + } + + Path walletPath = this.getCurrentWalletPath(); + Files.createDirectories(walletPath.getParent()); + Files.write(walletPath, wallet, StandardOpenOption.CREATE); + + LOGGER.debug("Saved Pirate Chain wallet"); + + return true; + } + + public String load() throws IOException { + if (this.isNullSeedWallet()) { + // Don't load wallets that have a null seed + return null; + } + Path walletPath = this.getCurrentWalletPath(); + if (!Files.exists(walletPath)) { + return null; + } + byte[] wallet = Files.readAllBytes(walletPath); + if (wallet == null) { + return null; + } + String wallet64 = Base64.toBase64String(wallet); + return wallet64; + } + + private String getEntropyHash58() { + if (this.entropyBytes == null) { + return null; + } + byte[] entropyHash = Crypto.digest(this.entropyBytes); + return Base58.encode(entropyHash); + } + + public String getSeedPhrase() { + return this.seedPhrase; + } + + private String getEncryptionKey() { + if (this.entropyBytes == null) { + return null; + } + + // Prefix the bytes with a (deterministic) string, to ensure that the resulting hash is different + String prefix = "ARRRWalletEncryption"; + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + try { + outputStream.write(prefix.getBytes(StandardCharsets.UTF_8)); + outputStream.write(this.entropyBytes); + + } catch (IOException e) { + return null; + } + + byte[] encryptionKeyHash = Crypto.digest(outputStream.toByteArray()); + return Base58.encode(encryptionKeyHash); + } + + private Path getCurrentWalletPath() { + String entropyHash58 = this.getEntropyHash58(); + String filename = String.format("wallet-%s.dat", entropyHash58); + return Paths.get(Settings.getInstance().getWalletsPath(), "PirateChain", filename); + } + + public boolean isInitialized() { + return this.entropyBytes != null && this.ready; + } + + public boolean isSynchronized() { + Integer height = this.getHeight(); + Integer chainTip = this.getChainTip(); + + if (height == null || chainTip == null) { + return false; + } + + // Assume synchronized if within 2 blocks of the chain tip + return height >= (chainTip - 2); + } + + + // APIs + + public Integer getHeight() { + String response = LiteWalletJni.execute("height", ""); + JSONObject json = new JSONObject(response); + if (json.has("height")) { + return json.getInt("height"); + } + return null; + } + + public Integer getChainTip() { + String response = LiteWalletJni.execute("info", ""); + JSONObject json = new JSONObject(response); + if (json.has("latest_block_height")) { + return json.getInt("latest_block_height"); + } + return null; + } + + public boolean isNullSeedWallet() { + return this.isNullSeedWallet; + } + + public Boolean isEncrypted() { + String response = LiteWalletJni.execute("encryptionstatus", ""); + JSONObject json = new JSONObject(response); + if (json.has("encrypted")) { + return json.getBoolean("encrypted"); + } + return null; + } + + public boolean doEncrypt(String key) { + String response = LiteWalletJni.execute("encrypt", key); + JSONObject json = new JSONObject(response); + String result = json.getString("result"); + if (json.has("result")) { + return (Objects.equals(result, "success")); + } + return false; + } + + public boolean doDecrypt(String key) { + String response = LiteWalletJni.execute("decrypt", key); + JSONObject json = new JSONObject(response); + String result = json.getString("result"); + if (json.has("result")) { + return (Objects.equals(result, "success")); + } + return false; + } + + public boolean doUnlock(String key) { + String response = LiteWalletJni.execute("unlock", key); + JSONObject json = new JSONObject(response); + String result = json.getString("result"); + if (json.has("result")) { + return (Objects.equals(result, "success")); + } + return false; + } + + public String getWalletAddress() { + // Get balance, which also contains wallet addresses + String response = LiteWalletJni.execute("balance", ""); + JSONObject json = new JSONObject(response); + String address = null; + + if (json.has("z_addresses")) { + JSONArray z_addresses = json.getJSONArray("z_addresses"); + + if (z_addresses != null && !z_addresses.isEmpty()) { + JSONObject firstAddress = z_addresses.getJSONObject(0); + if (firstAddress.has("address")) { + address = firstAddress.getString("address"); + } + } + } + return address; + } + + public String getPrivateKey() { + String response = LiteWalletJni.execute("export", ""); + JSONArray addressesJson = new JSONArray(response); + if (!addressesJson.isEmpty()) { + JSONObject addressJson = addressesJson.getJSONObject(0); + if (addressJson.has("private_key")) { + //String address = addressJson.getString("address"); + String privateKey = addressJson.getString("private_key"); + //String viewingKey = addressJson.getString("viewing_key"); + + return privateKey; + } + } + return null; + } + + public PirateLightClient.Server getRandomServer() { + PirateChain.PirateChainNet pirateChainNet = Settings.getInstance().getPirateChainNet(); + Collection servers = pirateChainNet.getServers(); + Random random = new Random(); + int index = random.nextInt(servers.size()); + return (PirateLightClient.Server) servers.toArray()[index]; + } + +} diff --git a/src/main/java/org/qortal/crosschain/SimpleTransaction.java b/src/main/java/org/qortal/crosschain/SimpleTransaction.java index 53039020..b61544d1 100644 --- a/src/main/java/org/qortal/crosschain/SimpleTransaction.java +++ b/src/main/java/org/qortal/crosschain/SimpleTransaction.java @@ -12,6 +12,7 @@ public class SimpleTransaction { private long feeAmount; private List inputs; private List outputs; + private String memo; @XmlAccessorType(XmlAccessType.FIELD) @@ -74,13 +75,14 @@ public class SimpleTransaction { public SimpleTransaction() { } - public SimpleTransaction(String txHash, Long timestamp, long totalAmount, long feeAmount, List inputs, List outputs) { + public SimpleTransaction(String txHash, Long timestamp, long totalAmount, long feeAmount, List inputs, List outputs, String memo) { this.txHash = txHash; this.timestamp = timestamp; this.totalAmount = totalAmount; this.feeAmount = feeAmount; this.inputs = inputs; this.outputs = outputs; + this.memo = memo; } public String getTxHash() { diff --git a/src/main/java/org/qortal/crosschain/SupportedBlockchain.java b/src/main/java/org/qortal/crosschain/SupportedBlockchain.java index b249293c..c1f68831 100644 --- a/src/main/java/org/qortal/crosschain/SupportedBlockchain.java +++ b/src/main/java/org/qortal/crosschain/SupportedBlockchain.java @@ -85,6 +85,20 @@ public enum SupportedBlockchain { public ACCT getLatestAcct() { return RavencoinACCTv3.getInstance(); } + }, + + PIRATECHAIN(Arrays.asList( + Triple.valueOf(PirateChainACCTv3.NAME, PirateChainACCTv3.CODE_BYTES_HASH, PirateChainACCTv3::getInstance) + )) { + @Override + public ForeignBlockchain getInstance() { + return PirateChain.getInstance(); + } + + @Override + public ACCT getLatestAcct() { + return PirateChainACCTv3.getInstance(); + } }; private static final Map> supportedAcctsByCodeHash = Arrays.stream(SupportedBlockchain.values()) diff --git a/src/main/java/org/qortal/crosschain/UnspentOutput.java b/src/main/java/org/qortal/crosschain/UnspentOutput.java index 86aa533d..9929d3be 100644 --- a/src/main/java/org/qortal/crosschain/UnspentOutput.java +++ b/src/main/java/org/qortal/crosschain/UnspentOutput.java @@ -7,10 +7,20 @@ public class UnspentOutput { public final int height; public final long value; - public UnspentOutput(byte[] hash, int index, int height, long value) { + // Optional fields returned by Pirate Light Client server + public final byte[] script; + public final String address; + + public UnspentOutput(byte[] hash, int index, int height, long value, byte[] script, String address) { this.hash = hash; this.index = index; this.height = height; this.value = value; + this.script = script; + this.address = address; + } + + public UnspentOutput(byte[] hash, int index, int height, long value) { + this(hash, index, height, value, null, null); } } \ No newline at end of file diff --git a/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceStatus.java b/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceStatus.java index 5e6ac055..b1fbbd3c 100644 --- a/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceStatus.java +++ b/src/main/java/org/qortal/data/arbitrary/ArbitraryResourceStatus.java @@ -26,6 +26,7 @@ public class ArbitraryResourceStatus { } } + private Status status; private String id; private String title; private String description; @@ -37,6 +38,7 @@ public class ArbitraryResourceStatus { } public ArbitraryResourceStatus(Status status, Integer localChunkCount, Integer totalChunkCount) { + this.status = status; this.id = status.toString(); this.title = status.title; this.description = status.description; @@ -47,4 +49,20 @@ public class ArbitraryResourceStatus { public ArbitraryResourceStatus(Status status) { this(status, null, null); } + + public Status getStatus() { + return this.status; + } + + public String getTitle() { + return this.title; + } + + public Integer getLocalChunkCount() { + return this.localChunkCount; + } + + public Integer getTotalChunkCount() { + return this.totalChunkCount; + } } diff --git a/src/main/java/org/qortal/network/Network.java b/src/main/java/org/qortal/network/Network.java index 10f02d52..57073e99 100644 --- a/src/main/java/org/qortal/network/Network.java +++ b/src/main/java/org/qortal/network/Network.java @@ -1375,26 +1375,17 @@ public class Network { // We attempted to connect within the last day // but we last managed to connect over a week ago. Predicate isNotOldPeer = peerData -> { - - // First check if there was a connection attempt within the last day - if (peerData.getLastAttempted() != null - && peerData.getLastAttempted() > now - OLD_PEER_ATTEMPTED_PERIOD) { - - // There was, so now check if we had a successful connection in the last 7 days - if (peerData.getLastConnected() != null - && peerData.getLastConnected() > now - OLD_PEER_CONNECTION_PERIOD) { - - // We did, so this is NOT an 'old' peer - return true; - } - - // Last successful connection was more than 1 week ago - this is an 'old' peer - return false; - } - else { - // Best to wait until we have a connection attempt - assume not an 'old' peer until then + if (peerData.getLastAttempted() == null + || peerData.getLastAttempted() < now - OLD_PEER_ATTEMPTED_PERIOD) { return true; } + + if (peerData.getLastConnected() == null + || peerData.getLastConnected() > now - OLD_PEER_CONNECTION_PERIOD) { + return true; + } + + return false; }; // Disregard peers that are NOT 'old' diff --git a/src/main/java/org/qortal/network/Peer.java b/src/main/java/org/qortal/network/Peer.java index f99a94b1..cac0ccc9 100644 --- a/src/main/java/org/qortal/network/Peer.java +++ b/src/main/java/org/qortal/network/Peer.java @@ -27,6 +27,8 @@ import java.nio.channels.SocketChannel; import java.security.SecureRandom; import java.util.*; import java.util.concurrent.*; +import java.util.concurrent.atomic.LongAccumulator; +import java.util.concurrent.atomic.LongAdder; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -153,6 +155,16 @@ public class Peer { */ private CommonBlockData commonBlockData; + // Message stats + + private static class MessageStats { + public final LongAdder count = new LongAdder(); + public final LongAdder totalBytes = new LongAdder(); + } + + private final Map receivedMessageStats = new ConcurrentHashMap<>(); + private final Map sentMessageStats = new ConcurrentHashMap<>(); + // Constructors /** @@ -542,11 +554,18 @@ public class Peer { // Tidy up buffers: this.byteBuffer.flip(); // Read-only, flipped buffer's position will be after end of message, so copy that + long messageByteSize = readOnlyBuffer.position(); this.byteBuffer.position(readOnlyBuffer.position()); // Copy bytes after read message to front of buffer, // adjusting position accordingly, reset limit to capacity this.byteBuffer.compact(); + // Record message stats + MessageStats messageStats = this.receivedMessageStats.computeIfAbsent(message.getType(), k -> new MessageStats()); + // Ideally these two operations would be atomic, we could pack 'count' in top X bits of the 64-bit long, but meh + messageStats.count.increment(); + messageStats.totalBytes.add(messageByteSize); + // Unsupported message type? Discard with no further processing if (message.getType() == MessageType.UNSUPPORTED) continue; @@ -609,6 +628,12 @@ public class Peer { LOGGER.trace("[{}] Sending {} message with ID {} to peer {}", this.peerConnectionId, this.outputMessageType, this.outputMessageId, this); + + // Record message stats + MessageStats messageStats = this.sentMessageStats.computeIfAbsent(message.getType(), k -> new MessageStats()); + // Ideally these two operations would be atomic, we could pack 'count' in top X bits of the 64-bit long, but meh + messageStats.count.increment(); + messageStats.totalBytes.add(this.outputBuffer.limit()); } catch (MessageException e) { // Something went wrong converting message to bytes, so discard but allow another round LOGGER.warn("[{}] Failed to send {} message with ID {} to peer {}: {}", this.peerConnectionId, @@ -799,8 +824,11 @@ public class Peer { } public void shutdown() { + boolean logStats = false; + if (!isStopping) { LOGGER.debug("[{}] Shutting down peer {}", this.peerConnectionId, this); + logStats = true; } isStopping = true; @@ -812,8 +840,34 @@ public class Peer { LOGGER.debug("[{}] IOException while trying to close peer {}", this.peerConnectionId, this); } } + + if (logStats && this.receivedMessageStats.size() > 0) { + StringBuilder statsBuilder = new StringBuilder(1024); + statsBuilder.append("peer ").append(this).append(" message stats:\n=received="); + appendMessageStats(statsBuilder, this.receivedMessageStats); + statsBuilder.append("\n=sent="); + appendMessageStats(statsBuilder, this.sentMessageStats); + + LOGGER.debug(statsBuilder.toString()); + } } + private static void appendMessageStats(StringBuilder statsBuilder, Map messageStats) { + if (messageStats.isEmpty()) { + statsBuilder.append("\n none"); + return; + } + + messageStats.keySet().stream() + .sorted(Comparator.comparing(MessageType::name)) + .forEach(messageType -> { + MessageStats stats = messageStats.get(messageType); + + statsBuilder.append("\n ").append(messageType.name()) + .append(": count=").append(stats.count.sum()) + .append(", total bytes=").append(stats.totalBytes.sum()); + }); + } // Minimum version diff --git a/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java b/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java index 71e5897d..1174f5c8 100644 --- a/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java +++ b/src/main/java/org/qortal/repository/hsqldb/HSQLDBDatabaseUpdates.java @@ -969,6 +969,12 @@ public class HSQLDBDatabaseUpdates { stmt.execute("ALTER TABLE Blocks ALTER COLUMN online_accounts SET DATA TYPE VARBINARY(10240)"); break; + case 43: + // Pirate Chain requires storing addresses that are 78 bytes long (69 bytes when decoded), so increase + // from 32 to 128 to give some padding for potentially even larger addresses in the future + stmt.execute("ALTER TABLE TradeBotStates ALTER COLUMN receiving_account_info SET DATA TYPE VARBINARY(128)"); + break; + default: // nothing to do return false; diff --git a/src/main/java/org/qortal/settings/Settings.java b/src/main/java/org/qortal/settings/Settings.java index ed4d3cd6..5b8d609e 100644 --- a/src/main/java/org/qortal/settings/Settings.java +++ b/src/main/java/org/qortal/settings/Settings.java @@ -28,6 +28,7 @@ import org.qortal.crosschain.Litecoin.LitecoinNet; import org.qortal.crosschain.Dogecoin.DogecoinNet; import org.qortal.crosschain.Digibyte.DigibyteNet; import org.qortal.crosschain.Ravencoin.RavencoinNet; +import org.qortal.crosschain.PirateChain.PirateChainNet; import org.qortal.utils.EnumUtils; // All properties to be converted to JSON via JAXB @@ -210,9 +211,9 @@ public class Settings { private boolean allowConnectionsWithOlderPeerVersions = true; /** Minimum time (in seconds) that we should attempt to remain connected to a peer for */ - private int minPeerConnectionTime = 5 * 60; // seconds + private int minPeerConnectionTime = 60 * 60; // seconds /** Maximum time (in seconds) that we should attempt to remain connected to a peer for */ - private int maxPeerConnectionTime = 60 * 60; // seconds + private int maxPeerConnectionTime = 4 * 60 * 60; // seconds /** Maximum time (in seconds) that a peer should remain connected when requesting QDN data */ private int maxDataPeerConnectionTime = 2 * 60; // seconds @@ -232,10 +233,16 @@ public class Settings { private DogecoinNet dogecoinNet = DogecoinNet.MAIN; private DigibyteNet digibyteNet = DigibyteNet.MAIN; private RavencoinNet ravencoinNet = RavencoinNet.MAIN; + private PirateChainNet pirateChainNet = PirateChainNet.MAIN; // Also crosschain-related: /** Whether to show SysTray pop-up notifications when trade-bot entries change state */ private boolean tradebotSystrayEnabled = false; + /** Wallets path - used for storing encrypted wallet caches for coins that require them */ + private String walletsPath = "wallets"; + + private int arrrDefaultBirthday = 2000000; + // Repository related /** Queries that take longer than this are logged. (milliseconds) */ private Long slowQueryThreshold = null; @@ -289,6 +296,16 @@ public class Settings { private boolean onlineAccountsMemPoWEnabled = false; + /* Foreign chains */ + + /** The number of consecutive empty addresses required before treating a wallet's transaction set as complete */ + private int gapLimit = 24; + + /** How many wallet keys to generate when using bitcoinj as the blockchain interface (e.g. when sending coins) */ + private int bitcoinjLookaheadSize = 50; + + + // Data storage (QDN) /** Data storage enabled/disabled*/ @@ -711,6 +728,18 @@ public class Settings { return this.ravencoinNet; } + public PirateChainNet getPirateChainNet() { + return this.pirateChainNet; + } + + public String getWalletsPath() { + return this.walletsPath; + } + + public int getArrrDefaultBirthday() { + return this.arrrDefaultBirthday; + } + public boolean isTradebotSystrayEnabled() { return this.tradebotSystrayEnabled; } @@ -881,6 +910,15 @@ public class Settings { } + public int getGapLimit() { + return this.gapLimit; + } + + public int getBitcoinjLookaheadSize() { + return bitcoinjLookaheadSize; + } + + public boolean isQdnEnabled() { return this.qdnEnabled; } diff --git a/src/main/java/org/qortal/utils/ArbitraryTransactionUtils.java b/src/main/java/org/qortal/utils/ArbitraryTransactionUtils.java index 9b81bd68..4c464bee 100644 --- a/src/main/java/org/qortal/utils/ArbitraryTransactionUtils.java +++ b/src/main/java/org/qortal/utils/ArbitraryTransactionUtils.java @@ -5,7 +5,10 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.arbitrary.ArbitraryDataFile; import org.qortal.arbitrary.ArbitraryDataFileChunk; +import org.qortal.arbitrary.ArbitraryDataReader; +import org.qortal.arbitrary.ArbitraryDataResource; import org.qortal.arbitrary.misc.Service; +import org.qortal.data.arbitrary.ArbitraryResourceStatus; import org.qortal.data.transaction.ArbitraryTransactionData; import org.qortal.data.transaction.TransactionData; import org.qortal.repository.DataException; @@ -410,4 +413,31 @@ public class ArbitraryTransactionUtils { return transactions.stream().skip(offset).limit(limit).collect(Collectors.toList()); } + + /** + * Lookup status of resource + * @param service + * @param name + * @param identifier + * @param build + * @return + */ + public static ArbitraryResourceStatus getStatus(Service service, String name, String identifier, Boolean build) { + + // If "build" has been specified, build the resource before returning its status + if (build != null && build == true) { + ArbitraryDataReader reader = new ArbitraryDataReader(name, ArbitraryDataFile.ResourceIdType.NAME, service, null); + try { + if (!reader.isBuilding()) { + reader.loadSynchronously(false); + } + } catch (Exception e) { + // No need to handle exception, as it will be reflected in the status + } + } + + ArbitraryDataResource resource = new ArbitraryDataResource(name, ArbitraryDataFile.ResourceIdType.NAME, service, identifier); + return resource.getStatus(false); + } + } diff --git a/src/main/java/org/qortal/utils/BitTwiddling.java b/src/main/java/org/qortal/utils/BitTwiddling.java index eda5b4f6..72bd83cc 100644 --- a/src/main/java/org/qortal/utils/BitTwiddling.java +++ b/src/main/java/org/qortal/utils/BitTwiddling.java @@ -1,5 +1,7 @@ package org.qortal.utils; +import java.nio.ByteBuffer; + public class BitTwiddling { /** @@ -48,4 +50,25 @@ public class BitTwiddling { | (bytes[start + 4] & 0xffL) << 24 | (bytes[start + 5] & 0xffL) << 16 | (bytes[start + 6] & 0xffL) << 8 | (bytes[start + 7] & 0xffL); } + /** Convert little-endian bytes to long */ + public static long longFromLEBytes(byte[] bytes, int start) { + return (bytes[start] & 0xffL) | (bytes[start + 1] & 0xffL) << 8 | (bytes[start + 2] & 0xffL) << 16 | (bytes[start + 3] & 0xffL) << 24 + | (bytes[start + 4] & 0xffL) << 32 | (bytes[start + 5] & 0xffL) << 40 | (bytes[start + 6] & 0xffL) << 48 | (bytes[start + 7] & 0xffL) << 56; + } + + + /** Read 8-bit unsigned integer from byte buffer */ + public static int readU8(ByteBuffer byteBuffer) { + byte[] sizeBytes = new byte[1]; + byteBuffer.get(sizeBytes); + return sizeBytes[0] & 0xff; + } + + /** Read 32-bit unsigned integer from byte buffer */ + public static int readU32(ByteBuffer byteBuffer) { + byte[] bytes = new byte[4]; + byteBuffer.get(bytes); + return BitTwiddling.intFromLEBytes(bytes, 0); + } + } diff --git a/src/main/resources/blockchain.json b/src/main/resources/blockchain.json index 38c5d66c..f1041485 100644 --- a/src/main/resources/blockchain.json +++ b/src/main/resources/blockchain.json @@ -23,7 +23,7 @@ "founderEffectiveMintingLevel": 10, "onlineAccountSignaturesMinLifetime": 43200000, "onlineAccountSignaturesMaxLifetime": 86400000, - "onlineAccountsModulusV2Timestamp": 9999999999999, + "onlineAccountsModulusV2Timestamp": 1659801600000, "onlineAccountsMemoryPoWTimestamp": 9999999999999, "rewardsByHeight": [ { "height": 1, "reward": 5.00 }, @@ -41,14 +41,16 @@ { "height": 3110401, "reward": 2.00 } ], "sharesByLevel": [ - { "levels": [ 1, 2 ], "share": 0.05 }, - { "levels": [ 3, 4 ], "share": 0.10 }, - { "levels": [ 5, 6 ], "share": 0.15 }, - { "levels": [ 7, 8 ], "share": 0.20 }, - { "levels": [ 9, 10 ], "share": 0.25 } + { "id": 1, "levels": [ 1, 2 ], "share": 0.05 }, + { "id": 2, "levels": [ 3, 4 ], "share": 0.10 }, + { "id": 3, "levels": [ 5, 6 ], "share": 0.15 }, + { "id": 4, "levels": [ 7, 8 ], "share": 0.20 }, + { "id": 5, "levels": [ 9, 10 ], "share": 0.25 } ], "qoraHoldersShare": 0.20, "qoraPerQortReward": 250, + "minAccountsToActivateShareBin": 30, + "shareBinActivationMinLevel": 7, "blocksNeededByLevel": [ 7200, 64800, 129600, 172800, 244000, 345600, 518400, 691200, 864000, 1036800 ], "blockTimingsByHeight": [ { "height": 1, "target": 60000, "deviation": 30000, "power": 0.2 } diff --git a/src/main/resources/proto/zcash/compact_formats.proto b/src/main/resources/proto/zcash/compact_formats.proto new file mode 100644 index 00000000..3ac774e7 --- /dev/null +++ b/src/main/resources/proto/zcash/compact_formats.proto @@ -0,0 +1,57 @@ +// Copyright (c) 2019-2020 The Zcash developers +// Copyright (c) 2019-2021 Pirate Chain developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +syntax = "proto3"; +package cash.z.wallet.sdk.rpc; +option go_package = "lightwalletd/walletrpc"; +option swift_prefix = ""; +// Remember that proto3 fields are all optional. A field that is not present will be set to its zero value. +// bytes fields of hashes are in canonical little-endian format. + +// CompactBlock is a packaging of ONLY the data from a block that's needed to: +// 1. Detect a payment to your shielded Sapling address +// 2. Detect a spend of your shielded Sapling notes +// 3. Update your witnesses to generate new Sapling spend proofs. +message CompactBlock { + uint32 protoVersion = 1; // the version of this wire format, for storage + uint64 height = 2; // the height of this block + bytes hash = 3; // the ID (hash) of this block, same as in block explorers + bytes prevHash = 4; // the ID (hash) of this block's predecessor + uint32 time = 5; // Unix epoch time when the block was mined + bytes header = 6; // (hash, prevHash, and time) OR (full header) + repeated CompactTx vtx = 7; // zero or more compact transactions from this block +} + +// CompactTx contains the minimum information for a wallet to know if this transaction +// is relevant to it (either pays to it or spends from it) via shielded elements +// only. This message will not encode a transparent-to-transparent transaction. +message CompactTx { + uint64 index = 1; // the index within the full block + bytes hash = 2; // the ID (hash) of this transaction, same as in block explorers + + // The transaction fee: present if server can provide. In the case of a + // stateless server and a transaction with transparent inputs, this will be + // unset because the calculation requires reference to prior transactions. + // in a pure-Sapling context, the fee will be calculable as: + // valueBalance + (sum(vPubNew) - sum(vPubOld) - sum(tOut)) + uint32 fee = 3; + + repeated CompactSpend spends = 4; // inputs + repeated CompactOutput outputs = 5; // outputs +} + +// CompactSpend is a Sapling Spend Description as described in 7.3 of the Zcash +// protocol specification. +message CompactSpend { + bytes nf = 1; // nullifier (see the Zcash protocol specification) +} + +// output is a Sapling Output Description as described in section 7.4 of the +// Zcash protocol spec. Total size is 948. +message CompactOutput { + bytes cmu = 1; // note commitment u-coordinate + bytes epk = 2; // ephemeral public key + bytes ciphertext = 3; // ciphertext and zkproof +} diff --git a/src/main/resources/proto/zcash/darkside.proto b/src/main/resources/proto/zcash/darkside.proto new file mode 100644 index 00000000..e2e03413 --- /dev/null +++ b/src/main/resources/proto/zcash/darkside.proto @@ -0,0 +1,117 @@ +// Copyright (c) 2019-2020 The Zcash developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +syntax = "proto3"; +package cash.z.wallet.sdk.rpc; +option go_package = "lightwalletd/walletrpc"; +option swift_prefix = ""; +import "service.proto"; + +message DarksideMetaState { + int32 saplingActivation = 1; + string branchID = 2; + string chainName = 3; +} + +// A block is a hex-encoded string. +message DarksideBlock { + string block = 1; +} + +// DarksideBlocksURL is typically something like: +// https://raw.githubusercontent.com/zcash-hackworks/darksidewalletd-test-data/master/basic-reorg/before-reorg.txt +message DarksideBlocksURL { + string url = 1; +} + +// DarksideTransactionsURL refers to an HTTP source that contains a list +// of hex-encoded transactions, one per line, that are to be associated +// with the given height (fake-mined into the block at that height) +message DarksideTransactionsURL { + int32 height = 1; + string url = 2; +} + +message DarksideHeight { + int32 height = 1; +} + +message DarksideEmptyBlocks { + int32 height = 1; + int32 nonce = 2; + int32 count = 3; +} + +// Darksidewalletd maintains two staging areas, blocks and transactions. The +// Stage*() gRPCs add items to the staging area; ApplyStaged() "applies" everything +// in the staging area to the working (operational) state that the mock zcashd +// serves; transactions are placed into their corresponding blocks (by height). +service DarksideStreamer { + // Reset reverts all darksidewalletd state (active block range, latest height, + // staged blocks and transactions) and lightwalletd state (cache) to empty, + // the same as the initial state. This occurs synchronously and instantaneously; + // no reorg happens in lightwalletd. This is good to do before each independent + // test so that no state leaks from one test to another. + // Also sets (some of) the values returned by GetLightdInfo(). The Sapling + // activation height specified here must be where the block range starts. + rpc Reset(DarksideMetaState) returns (Empty) {} + + // StageBlocksStream accepts a list of blocks and saves them into the blocks + // staging area until ApplyStaged() is called; there is no immediate effect on + // the mock zcashd. Blocks are hex-encoded. Order is important, see ApplyStaged. + rpc StageBlocksStream(stream DarksideBlock) returns (Empty) {} + + // StageBlocks is the same as StageBlocksStream() except the blocks are fetched + // from the given URL. Blocks are one per line, hex-encoded (not JSON). + rpc StageBlocks(DarksideBlocksURL) returns (Empty) {} + + // StageBlocksCreate is like the previous two, except it creates 'count' + // empty blocks at consecutive heights starting at height 'height'. The + // 'nonce' is part of the header, so it contributes to the block hash; this + // lets you create identical blocks (same transactions and height), but with + // different hashes. + rpc StageBlocksCreate(DarksideEmptyBlocks) returns (Empty) {} + + // StageTransactionsStream stores the given transaction-height pairs in the + // staging area until ApplyStaged() is called. Note that these transactions + // are not returned by the production GetTransaction() gRPC until they + // appear in a "mined" block (contained in the active blockchain presented + // by the mock zcashd). + rpc StageTransactionsStream(stream RawTransaction) returns (Empty) {} + + // StageTransactions is the same except the transactions are fetched from + // the given url. They are all staged into the block at the given height. + // Staging transactions to different heights requires multiple calls. + rpc StageTransactions(DarksideTransactionsURL) returns (Empty) {} + + // ApplyStaged iterates the list of blocks that were staged by the + // StageBlocks*() gRPCs, in the order they were staged, and "merges" each + // into the active, working blocks list that the mock zcashd is presenting + // to lightwalletd. Even as each block is applied, the active list can't + // have gaps; if the active block range is 1000-1006, and the staged block + // range is 1003-1004, the resulting range is 1000-1004, with 1000-1002 + // unchanged, blocks 1003-1004 from the new range, and 1005-1006 dropped. + // + // After merging all blocks, ApplyStaged() appends staged transactions (in + // the order received) into each one's corresponding (by height) block + // The staging area is then cleared. + // + // The argument specifies the latest block height that mock zcashd reports + // (i.e. what's returned by GetLatestBlock). Note that ApplyStaged() can + // also be used to simply advance the latest block height presented by mock + // zcashd. That is, there doesn't need to be anything in the staging area. + rpc ApplyStaged(DarksideHeight) returns (Empty) {} + + // Calls to the production gRPC SendTransaction() store the transaction in + // a separate area (not the staging area); this method returns all transactions + // in this separate area, which is then cleared. The height returned + // with each transaction is -1 (invalid) since these transactions haven't + // been mined yet. The intention is that the transactions returned here can + // then, for example, be given to StageTransactions() to get them "mined" + // into a specified block on the next ApplyStaged(). + rpc GetIncomingTransactions(Empty) returns (stream RawTransaction) {} + + // Clear the incoming transaction pool. + rpc ClearIncomingTransactions(Empty) returns (Empty) {} +} diff --git a/src/main/resources/proto/zcash/service.proto b/src/main/resources/proto/zcash/service.proto new file mode 100644 index 00000000..74230bcd --- /dev/null +++ b/src/main/resources/proto/zcash/service.proto @@ -0,0 +1,181 @@ +// Copyright (c) 2019-2020 The Zcash developers +// Copyright (c) 2019-2021 Pirate Chain developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://www.opensource.org/licenses/mit-license.php . + +syntax = "proto3"; +package cash.z.wallet.sdk.rpc; +option go_package = "lightwalletd/walletrpc"; +option swift_prefix = ""; +import "compact_formats.proto"; + +// A BlockID message contains identifiers to select a block: a height or a +// hash. Specification by hash is not implemented, but may be in the future. +message BlockID { + uint64 height = 1; + bytes hash = 2; +} + +// BlockRange specifies a series of blocks from start to end inclusive. +// Both BlockIDs must be heights; specification by hash is not yet supported. +message BlockRange { + BlockID start = 1; + BlockID end = 2; +} + +// A TxFilter contains the information needed to identify a particular +// transaction: either a block and an index, or a direct transaction hash. +// Currently, only specification by hash is supported. +message TxFilter { + BlockID block = 1; // block identifier, height or hash + uint64 index = 2; // index within the block + bytes hash = 3; // transaction ID (hash, txid) +} + +// RawTransaction contains the complete transaction data. It also optionally includes +// the block height in which the transaction was included. +message RawTransaction { + bytes data = 1; // exact data returned by Zcash 'getrawtransaction' + uint64 height = 2; // height that the transaction was mined (or -1) +} + +// A SendResponse encodes an error code and a string. It is currently used +// only by SendTransaction(). If error code is zero, the operation was +// successful; if non-zero, it and the message specify the failure. +message SendResponse { + int32 errorCode = 1; + string errorMessage = 2; +} + +// Chainspec is a placeholder to allow specification of a particular chain fork. +message ChainSpec {} + +// Empty is for gRPCs that take no arguments, currently only GetLightdInfo. +message Empty {} + +// LightdInfo returns various information about this lightwalletd instance +// and the state of the blockchain. +message LightdInfo { + string version = 1; + string vendor = 2; + bool taddrSupport = 3; // true + string chainName = 4; // either "main" or "test" + uint64 saplingActivationHeight = 5; // depends on mainnet or testnet + string consensusBranchId = 6; // protocol identifier, see consensus/upgrades.cpp + uint64 blockHeight = 7; // latest block on the best chain + string gitCommit = 8; + string branch = 9; + string buildDate = 10; + string buildUser = 11; + uint64 estimatedHeight = 12; // less than tip height if pirated is syncing + string piratedBuild = 13; // example: "v4.1.1-877212414" + string piratedSubversion = 14; // example: "/MagicBean:4.1.1/" +} + +// TransparentAddressBlockFilter restricts the results to the given address +// or block range. +message TransparentAddressBlockFilter { + string address = 1; // t-address + BlockRange range = 2; // start, end heights +} + +// Duration is currently used only for testing, so that the Ping rpc +// can simulate a delay, to create many simultaneous connections. Units +// are microseconds. +message Duration { + int64 intervalUs = 1; +} + +// PingResponse is used to indicate concurrency, how many Ping rpcs +// are executing upon entry and upon exit (after the delay). +// This rpc is used for testing only. +message PingResponse { + int64 entry = 1; + int64 exit = 2; +} + +message Address { + string address = 1; +} +message AddressList { + repeated string addresses = 1; +} +message Balance { + int64 valueZat = 1; +} + +message Exclude { + repeated bytes txid = 1; +} + +// The TreeState is derived from the Zcash z_gettreestate rpc. +message TreeState { + string network = 1; // "main" or "test" + uint64 height = 2; + string hash = 3; // block id + uint32 time = 4; // Unix epoch time when the block was mined + string tree = 5; // sapling commitment tree state +} + +// Results are sorted by height, which makes it easy to issue another +// request that picks up from where the previous left off. +message GetAddressUtxosArg { + repeated string addresses = 1; + uint64 startHeight = 2; + uint32 maxEntries = 3; // zero means unlimited +} +message GetAddressUtxosReply { + string address = 6; + bytes txid = 1; + int32 index = 2; + bytes script = 3; + int64 valueZat = 4; + uint64 height = 5; +} +message GetAddressUtxosReplyList { + repeated GetAddressUtxosReply addressUtxos = 1; +} + +service CompactTxStreamer { + // Return the height of the tip of the best chain + rpc GetLatestBlock(ChainSpec) returns (BlockID) {} + // Return the compact block corresponding to the given block identifier + rpc GetBlock(BlockID) returns (CompactBlock) {} + // Return a list of consecutive compact blocks + rpc GetBlockRange(BlockRange) returns (stream CompactBlock) {} + + // Return the requested full (not compact) transaction (as from pirated) + rpc GetTransaction(TxFilter) returns (RawTransaction) {} + // Submit the given transaction to the Zcash network + rpc SendTransaction(RawTransaction) returns (SendResponse) {} + + // Return the txids corresponding to the given t-address within the given block range + rpc GetTaddressTxids(TransparentAddressBlockFilter) returns (stream RawTransaction) {} + rpc GetTaddressBalance(AddressList) returns (Balance) {} + rpc GetTaddressBalanceStream(stream Address) returns (Balance) {} + + // Return the compact transactions currently in the mempool; the results + // can be a few seconds out of date. If the Exclude list is empty, return + // all transactions; otherwise return all *except* those in the Exclude list + // (if any); this allows the client to avoid receiving transactions that it + // already has (from an earlier call to this rpc). The transaction IDs in the + // Exclude list can be shortened to any number of bytes to make the request + // more bandwidth-efficient; if two or more transactions in the mempool + // match a shortened txid, they are all sent (none is excluded). Transactions + // in the exclude list that don't exist in the mempool are ignored. + rpc GetMempoolTx(Exclude) returns (stream CompactTx) {} + + // GetTreeState returns the note commitment tree state corresponding to the given block. + // See section 3.7 of the Zcash protocol specification. It returns several other useful + // values also (even though they can be obtained using GetBlock). + // The block can be specified by either height or hash. + rpc GetTreeState(BlockID) returns (TreeState) {} + + rpc GetAddressUtxos(GetAddressUtxosArg) returns (GetAddressUtxosReplyList) {} + rpc GetAddressUtxosStream(GetAddressUtxosArg) returns (stream GetAddressUtxosReply) {} + + // Return information about this lightwalletd instance and the blockchain + rpc GetLightdInfo(Empty) returns (LightdInfo) {} + // Testing-only, requires lightwalletd --ping-very-insecure (do not enable in production) + rpc Ping(Duration) returns (PingResponse) {} +} diff --git a/src/test/java/org/qortal/test/crosschain/BitcoinTests.java b/src/test/java/org/qortal/test/crosschain/BitcoinTests.java index af879e08..07a01ce2 100644 --- a/src/test/java/org/qortal/test/crosschain/BitcoinTests.java +++ b/src/test/java/org/qortal/test/crosschain/BitcoinTests.java @@ -81,7 +81,7 @@ public class BitcoinTests extends Common { } @Test - public void testGetWalletBalance() { + public void testGetWalletBalance() throws ForeignBlockchainException { String xprv58 = "tprv8ZgxMBicQKsPdahhFSrCdvC1bsWyzHHZfTneTVqUXN6s1wEtZLwAkZXzFP6TYLg2aQMecZLXLre5bTVGajEB55L1HYJcawpdFG66STVAWPJ"; Long balance = bitcoin.getWalletBalance(xprv58); diff --git a/src/test/java/org/qortal/test/crosschain/DigibyteTests.java b/src/test/java/org/qortal/test/crosschain/DigibyteTests.java index 1810d7ed..dbe81c82 100644 --- a/src/test/java/org/qortal/test/crosschain/DigibyteTests.java +++ b/src/test/java/org/qortal/test/crosschain/DigibyteTests.java @@ -81,7 +81,7 @@ public class DigibyteTests extends Common { } @Test - public void testGetWalletBalance() { + public void testGetWalletBalance() throws ForeignBlockchainException { String xprv58 = "xpub661MyMwAqRbcEnabTLX5uebYcsE3uG5y7ve9jn1VK8iY1MaU3YLoLJEe8sTu2YVav5Zka5qf2dmMssfxmXJTqZnazZL2kL7M2tNKwEoC34R"; Long balance = digibyte.getWalletBalance(xprv58); diff --git a/src/test/java/org/qortal/test/crosschain/DogecoinTests.java b/src/test/java/org/qortal/test/crosschain/DogecoinTests.java index 2b0410c3..6c070d09 100644 --- a/src/test/java/org/qortal/test/crosschain/DogecoinTests.java +++ b/src/test/java/org/qortal/test/crosschain/DogecoinTests.java @@ -81,7 +81,7 @@ public class DogecoinTests extends Common { } @Test - public void testGetWalletBalance() { + public void testGetWalletBalance() throws ForeignBlockchainException { String xprv58 = "dgpv51eADS3spNJh9drNeW1Tc1P9z2LyaQRXPBortsq6yice1k47C2u2Prvgxycr2ihNBWzKZ2LthcBBGiYkWZ69KUTVkcLVbnjq7pD8mnApEru"; Long balance = dogecoin.getWalletBalance(xprv58); diff --git a/src/test/java/org/qortal/test/crosschain/LitecoinTests.java b/src/test/java/org/qortal/test/crosschain/LitecoinTests.java index 64837347..6236483a 100644 --- a/src/test/java/org/qortal/test/crosschain/LitecoinTests.java +++ b/src/test/java/org/qortal/test/crosschain/LitecoinTests.java @@ -80,7 +80,7 @@ public class LitecoinTests extends Common { } @Test - public void testGetWalletBalance() { + public void testGetWalletBalance() throws ForeignBlockchainException { String xprv58 = "tprv8ZgxMBicQKsPdahhFSrCdvC1bsWyzHHZfTneTVqUXN6s1wEtZLwAkZXzFP6TYLg2aQMecZLXLre5bTVGajEB55L1HYJcawpdFG66STVAWPJ"; Long balance = litecoin.getWalletBalance(xprv58); diff --git a/src/test/java/org/qortal/test/crosschain/PirateChainTests.java b/src/test/java/org/qortal/test/crosschain/PirateChainTests.java new file mode 100644 index 00000000..d203cf5e --- /dev/null +++ b/src/test/java/org/qortal/test/crosschain/PirateChainTests.java @@ -0,0 +1,297 @@ +package org.qortal.test.crosschain; + +import cash.z.wallet.sdk.rpc.CompactFormats.*; +import com.google.common.hash.HashCode; +import com.google.common.primitives.Bytes; +import org.bitcoinj.core.Transaction; +import org.bitcoinj.store.BlockStoreException; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.qortal.controller.tradebot.TradeBot; +import org.qortal.crosschain.*; +import org.qortal.crypto.Crypto; +import org.qortal.repository.DataException; +import org.qortal.test.common.Common; +import org.qortal.transform.TransformationException; + +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.*; +import static org.qortal.crosschain.PirateChainHTLC.Status.*; + +public class PirateChainTests extends Common { + + private PirateChain pirateChain; + + @Before + public void beforeTest() throws DataException { + Common.useDefaultSettings(); + pirateChain = PirateChain.getInstance(); + } + + @After + public void afterTest() { + Litecoin.resetForTesting(); + pirateChain = null; + } + + @Test + public void testGetMedianBlockTime() throws BlockStoreException, ForeignBlockchainException { + long before = System.currentTimeMillis(); + System.out.println(String.format("Pirate Chain median blocktime: %d", pirateChain.getMedianBlockTime())); + long afterFirst = System.currentTimeMillis(); + + System.out.println(String.format("Pirate Chain median blocktime: %d", pirateChain.getMedianBlockTime())); + long afterSecond = System.currentTimeMillis(); + + long firstPeriod = afterFirst - before; + long secondPeriod = afterSecond - afterFirst; + + System.out.println(String.format("1st call: %d ms, 2nd call: %d ms", firstPeriod, secondPeriod)); + + assertTrue("1st call should take less than 5 seconds", firstPeriod < 5000L); + assertTrue("2nd call should take less than 5 seconds", secondPeriod < 5000L); + } + + @Test + public void testGetCompactBlocks() throws ForeignBlockchainException { + int startHeight = 1000000; + int count = 20; + + long before = System.currentTimeMillis(); + List compactBlocks = pirateChain.getCompactBlocks(startHeight, count); + long after = System.currentTimeMillis(); + + System.out.println(String.format("Retrieval took: %d ms", after-before)); + + for (CompactBlock block : compactBlocks) { + System.out.println(String.format("Block height: %d, transaction count: %d", block.getHeight(), block.getVtxCount())); + } + + assertEquals(count, compactBlocks.size()); + } + + @Test + public void testGetRawTransaction() throws ForeignBlockchainException { + String txHashLE = "fea4b0c1abcf8f0f3ddc2fa2f9438501ee102aad62a9ff18a5ce7d08774755c0"; + byte[] txBytes = HashCode.fromString(txHashLE).asBytes(); + // Pirate protocol expects txids in big-endian form, but block explorers use txids in little-endian form + Bytes.reverse(txBytes); + String txHashBE = HashCode.fromBytes(txBytes).toString(); + + byte[] rawTransaction = pirateChain.getBlockchainProvider().getRawTransaction(txHashBE); + assertNotNull(rawTransaction); + } + + @Test + public void testDeriveP2SHAddressWithT3Prefix() { + byte[] creatorTradePrivateKey = TradeBot.generateTradePrivateKey(); + byte[] creatorTradeForeignPublicKey = TradeBot.deriveTradeForeignPublicKey(creatorTradePrivateKey); + byte[] tradePrivateKey = TradeBot.generateTradePrivateKey(); + byte[] tradeForeignPublicKey = TradeBot.deriveTradeForeignPublicKey(tradePrivateKey); + byte[] secretA = TradeBot.generateSecret(); + byte[] hashOfSecretA = Crypto.hash160(secretA); + int lockTime = 1653233550; + + byte[] redeemScriptBytes = PirateChainHTLC.buildScript(tradeForeignPublicKey, lockTime, creatorTradeForeignPublicKey, hashOfSecretA); + String p2shAddress = PirateChain.getInstance().deriveP2shAddress(redeemScriptBytes); + assertTrue(p2shAddress.startsWith("t3")); + } + + @Test + public void testDeriveP2SHAddressWithBPrefix() { + byte[] creatorTradePrivateKey = TradeBot.generateTradePrivateKey(); + byte[] creatorTradeForeignPublicKey = TradeBot.deriveTradeForeignPublicKey(creatorTradePrivateKey); + byte[] tradePrivateKey = TradeBot.generateTradePrivateKey(); + byte[] tradeForeignPublicKey = TradeBot.deriveTradeForeignPublicKey(tradePrivateKey); + byte[] secretA = TradeBot.generateSecret(); + byte[] hashOfSecretA = Crypto.hash160(secretA); + int lockTime = 1653233550; + + byte[] redeemScriptBytes = PirateChainHTLC.buildScript(tradeForeignPublicKey, lockTime, creatorTradeForeignPublicKey, hashOfSecretA); + String p2shAddress = PirateChain.getInstance().deriveP2shAddressBPrefix(redeemScriptBytes); + assertTrue(p2shAddress.startsWith("b")); + } + + @Test + public void testHTLCStatusFunded() throws ForeignBlockchainException { + String p2shAddress = "ba6Q5HWrWtmfU2WZqQbrFdRYsafA45cUAt"; + long p2shFee = 10000; + final long minimumAmount = 10000 + p2shFee; + PirateChainHTLC.Status htlcStatus = PirateChainHTLC.determineHtlcStatus(pirateChain.getBlockchainProvider(), p2shAddress, minimumAmount); + assertEquals(FUNDED, htlcStatus); + } + + @Test + public void testHTLCStatusRedeemed() throws ForeignBlockchainException { + String p2shAddress = "bYZrzSSgGp8aEGvihukoMGU8sXYrx19Wka"; + long p2shFee = 10000; + final long minimumAmount = 10000 + p2shFee; + PirateChainHTLC.Status htlcStatus = PirateChainHTLC.determineHtlcStatus(pirateChain.getBlockchainProvider(), p2shAddress, minimumAmount); + assertEquals(REDEEMED, htlcStatus); + } + + @Test + public void testHTLCStatusRefunded() throws ForeignBlockchainException { + String p2shAddress = "bE49izfVxz8odhu8c2BcUaVFUnt7NLFRgv"; + long p2shFee = 10000; + final long minimumAmount = 10000 + p2shFee; + PirateChainHTLC.Status htlcStatus = PirateChainHTLC.determineHtlcStatus(pirateChain.getBlockchainProvider(), p2shAddress, minimumAmount); + assertEquals(REFUNDED, htlcStatus); + } + + @Test + public void testGetTxidForUnspentAddress() throws ForeignBlockchainException { + String p2shAddress = "ba6Q5HWrWtmfU2WZqQbrFdRYsafA45cUAt"; + String txid = PirateChainHTLC.getFundingTxid(pirateChain.getBlockchainProvider(), p2shAddress); + + // Reverse the byte order of the txid used by block explorers, to get to big-endian form + byte[] expectedTxidLE = HashCode.fromString("fea4b0c1abcf8f0f3ddc2fa2f9438501ee102aad62a9ff18a5ce7d08774755c0").asBytes(); + Bytes.reverse(expectedTxidLE); + String expectedTxidBE = HashCode.fromBytes(expectedTxidLE).toString(); + + assertEquals(expectedTxidBE, txid); + } + + @Test + public void testGetTxidForUnspentAddressWithMinimumAmount() throws ForeignBlockchainException { + String p2shAddress = "ba6Q5HWrWtmfU2WZqQbrFdRYsafA45cUAt"; + long p2shFee = 10000; + final long minimumAmount = 10000 + p2shFee; + String txid = PirateChainHTLC.getUnspentFundingTxid(pirateChain.getBlockchainProvider(), p2shAddress, minimumAmount); + + // Reverse the byte order of the txid used by block explorers, to get to big-endian form + byte[] expectedTxidLE = HashCode.fromString("fea4b0c1abcf8f0f3ddc2fa2f9438501ee102aad62a9ff18a5ce7d08774755c0").asBytes(); + Bytes.reverse(expectedTxidLE); + String expectedTxidBE = HashCode.fromBytes(expectedTxidLE).toString(); + + assertEquals(expectedTxidBE, txid); + } + + @Test + public void testGetTxidForSpentAddress() throws ForeignBlockchainException { + String p2shAddress = "bE49izfVxz8odhu8c2BcUaVFUnt7NLFRgv"; //"t3KtVxeEb8srJofo6atMEpMpEP6TjEi8VqA"; + String txid = PirateChainHTLC.getFundingTxid(pirateChain.getBlockchainProvider(), p2shAddress); + + // Reverse the byte order of the txid used by block explorers, to get to big-endian form + byte[] expectedTxidLE = HashCode.fromString("fb386fc8eea0fbf3ea37047726b92c39441652b32d8d62a274331687f7a1eca8").asBytes(); + Bytes.reverse(expectedTxidLE); + String expectedTxidBE = HashCode.fromBytes(expectedTxidLE).toString(); + + assertEquals(expectedTxidBE, txid); + } + + @Test + public void testGetTransactionsForAddress() throws ForeignBlockchainException { + String p2shAddress = "bE49izfVxz8odhu8c2BcUaVFUnt7NLFRgv"; //"t3KtVxeEb8srJofo6atMEpMpEP6TjEi8VqA"; + List transactions = pirateChain.getBlockchainProvider() + .getAddressBitcoinyTransactions(p2shAddress, false); + + assertEquals(2, transactions.size()); + } + + @Test + public void testDecodeRawP2SHTransaction() throws TransformationException { + String transactionDataHex = "0400008085202f890002204e00000000000017a9140e8a360d8a54e3d684b7b43c293c6b26ca594abf8700000000000000006e6a4c6b630400738762b17521029ddc2860644ef2a3b6c7310432e2f4231f21171e26f04150363340cd17565ac8ac6782012088a914ab08c6bf2771e0b287303cc14cc02a6bd41a1fad8821029ddc2860644ef2a3b6c7310432e2f4231f21171e26f04150363340cd17565ac8ac6800000000b21e1d0030750000000000000136f025c5ec654eac6aae884c46162aceb7bc3dfd8a800de7adc01c7aef4c85f158ba30e0c4ed45509db91d76f60f6a35f0fd1fcbbac3019d83daa90bc1e05a28b13dcfc12225817a634b86594447e179915dd57accaae2a034d5c66171300e5a91fd576d08f60577a5518a66363349ef2c33771702aa91dfc15ca6bf32506899a2e90488edd6d7c5199476438f10b5c88d49768a5433930a1793aad1303ce0db48af74e0e7edc4104ced5214a94ee0d580fd3b6efbcab863a05c35d320b987fa58968e7f49f6d103dc5a45635d3ac2243eca854256f9ed856d352951402f9b860133ad082e2a1e3330d9923d216917ace5a5bcc350666be0fee214b667faef3df5e23e21d9cabaa90004a11446c20cc0a4756c7712b7b51d3906de8a6ba09114c26aa97ee5f833932a40dcadb830d216c84ded926738b57aaf33a34e0081e5526d8608db1a7008ead9387a3ae9ad4825b2068563363fdaacb860b2cab9e551407b35aa33a46960617df24ab075b9a399f721daa4b16926e44968c3fc15267704024db9f6ca6a09a3f46739f478190da73184e405866a31ee41dec2d633160eedabf9d5d7f361407fb3346ea4a26060b72ca70924745730e8821a22699fb96cff54f0a4270cadfb81193df48e0f573247ebd44b2e10fcd67e3877a4faf028324006d12dbb40b690351ca5ee2514ab5fdbabc21fd9ed9c03f98d45a97f10718d680bd83620187fd9b7093e406cbace69f11a729af72edcbf10eebd8bba7148be19380f6db7a246b9c1fcd238282d050d2000430544893843e5ab2e10d65156e7810bf4eb6401889ab55d7c8ae0cf901239f0e8532a47f161b1771895480173ef64202136d6c04635b78878e12782eabe20dd781f50138a2d7cc55d73070299b8fa1ae9a6a388b9b5c9b01b86feb20d14e7c48b03ff041eac240b2918b0ad1c5fe2f8c03591f6aa0860c87f9d4abd70b842d522629d8fdb7436ea4e2de7b4a2b119ed3d042ed75ad22f2ae6d16abeb3b7a2a7479acf8788184e1058aab5dee0b4ac105f33c57a5a0ba5744ef5de6a65a0ee99988da509c1d0f1e939204619276d29d5f5eecf2850c206dc112e34f06b37341cde63577dfb93c75623f102dd8b3413c31bf38ba04f438df22de81cf42720d6265de2593b6938a82c949c295c546d2343e37104220be8d32172706e205e246e787800357ddc4a10a1b3ec98ae38f6886e40ef2c8e5c3841f60a80d88263e286f66567892d49e63298024d02ce47926a6292cfc03ad03d559cc13a0b1562ea28f9fa1d6496cec47e6743deed4f266bc23b32a3196ba71e29cdce85833129b0777bbdbfd22c45d208ff71d79ca267d6b8556130677147a18b58f72d6628c20bdc87933ae1ec1a7c3a7b1efceb87739b99b785de32bb65e37014e84f905f1d288b927607759184f05cd41ace1f154397eaa4436710328dffcc95dc16399c449e3aabfd87ee160b971def1464c11cdd49609b8c6bf7892badd5483705fcfdfbe0b0345078a5c869245b7dddebef35853dbbefa3527e74d31d9db453251fc0e2b1ef3209e783a696b90ca915bfbaef58161ae8496d16f93d1f05ca9bbf1d2278bddaedf29c2b9e98bcfa5526d229896ed1b50dc71a607805f207eae23fba8a190f57dcbdf1db50e923828970fff049c10f6510e88a9c2fb9e0d1846fadf8ff8c739834cf7570cad2a84a6be4cd78c2344ef1f8745d41517fb825617ecdf0cea098b9f9ed4ba70710e55a0cff793d05b77bbf63f26bc4bec8eabd482c19f1ba6b79a11302763228a3af8bd309b7bad297adccfe6b9033bca82474058ecf2560ff4bbb49f5ea22cb2aa58997013f1c363c9d089264a0e3adbcf1b5a2f8e3440b43f3272e0ada44f4a1f43e549fe6c105752c3eb13b496dbbe65e761e0b0552a004b7854388778449be9726f00e600dcdabfd4aedfb93cb4280c338f23e020903ce1215e4b4158527bc427c8179ec20198a4c0728142a5fca870514a15bf07f9d4eb40e1ca4e67719b23eac04c57276cc7808ac060cb3966940ec4323a0cd3700a1b1189bd31d39e2fe47356781df65547c11e221aca1b80c16304fc33fa070b9b0a5032b967ce4b70257d1d7ff0d6085e0aa1b3f87ceda747c765f095624237ece471bd7c70f5e2e7f8db38036bc6a2a0d7562e0cdd03f05fb7828eb82511c5c843c2577e97151724c1ce5f365fe1cf57ec8ad09a71b5a6732be7bb1b374c26b870b3a2d2b61d889e5d7f2aab13f54774e183950ac7d578b336a658a567056fb26e305875cf4928a9a35e27391f0287f79cc2b6ec77ddc5363001d03ca835ff5aca983805990b233c1d1289fb06083c4c922052c3e4b5575aef9724bcaad5d60a73a7ef00063b0fafa1a5ebdcf745717e30d9293c9b450b70a3c83b902f3d4085e021f0b06ddfcdc2f4258c5f09439dca31f0c54f4998c36e1c53e2cfacdafad4a6a09f8c87ed07c0fd28ec9a83daf222562b3bcab982a29a9480da9166060cf2e8ac69df5def38c8dc6a6638999a559004926402ec597fd3d918a844c6d1ae3e949aafad667a224cbf3441a988f6e0478e513b60b3d51031f1fa4b08d2124e18f585c31429180f18b67b5dd8d33f82caa3e269f3ef7934e9d9192608edda8cc2fe40fd9458a9e832bd6a39e4a5cb0d14fc9f1fda53e127cc1246ab416321c61068c0868ad00cd84577f0347f6b03429b6f7d51982d2b818cdbbb30e89d0d43a2e84f74ec8780e5dd42f8dec0ff80fa56b889604d6617a59b89c50321adf5d8db7ad7bfc1329d8f0aba0408951142619a41ba74a905956407193b666a2e9bd90a5135210274971f4f036453db9218ac5b9e5417a5335abfdc8ed466538a4ac8df4fca5da5f92dbc1833f1b585194119eeb5487925d8ac89eea529ad72550072de6e43efc983c50043d6c1f677c83bcde80d265dd0efe7c12d0bb95178c0a45c7dc55b2ce6d0ef9a897b31b5d18a0dfe0db982c503b58950b471bf4003109f661844aa4197f11cd2d9f1153f5b6bd32b87919c4069ee810eb1bdb70f95f6be42d39915451da63a85979ed6836614874cd72ebfc61df8f61181482531405c6dfde5be00d7ba0c30c751ca511498b6cc14f427d3fdd40f5550236786f933e2913a4bb6e0620efcc191f1d434c2eaeb29a52775b41a32e2344bcf0912eaf674d2c83b8eea225794e4ed88fc761e0ecbd9a2ca747de1415f7bb254c11482500e0603cc470f2d1b09e462247846d714a12c55f9defa18f361576e7d4f39d69d56d786c8297ec8eb9421022aa057cfb02d5cd4a1abd0257f4aa425e148536df05"; + BitcoinyTransaction bitcoinyTransaction = PirateChain.deserializeRawTransaction(transactionDataHex); + assertEquals(0, bitcoinyTransaction.inputs.size()); + assertEquals(2, bitcoinyTransaction.outputs.size()); + assertEquals("a9140e8a360d8a54e3d684b7b43c293c6b26ca594abf87", bitcoinyTransaction.outputs.get(0).scriptPubKey); + assertEquals("6a4c6b630400738762b17521029ddc2860644ef2a3b6c7310432e2f4231f21171e26f04150363340cd17565ac8ac6782012088a914ab08c6bf2771e0b287303cc14cc02a6bd41a1fad8821029ddc2860644ef2a3b6c7310432e2f4231f21171e26f04150363340cd17565ac8ac68", bitcoinyTransaction.outputs.get(1).scriptPubKey); + assertEquals(0, bitcoinyTransaction.locktime); + } + + @Test + public void testDecodeRawRedeemTransaction() throws TransformationException { + String transactionDataHex = "0400008085202f8901efb7c5be4e870464795737109ed02b6c9b5e60e8676f68245c390b4cab09917e00000000d847304402203929739d51dbc4b4d3435cf8b4930101601f670b3e8bcb23fde122b870385fba0220195aed5ed09b7dd342906c67c8da2896d00049bc75127c96724d03b7981fdbd80120baa6e68ffb2ddf19df6fce1b37d7e38b98f3706d5709e46d4f45f71c2e4bb7c301004c6b630436798662b17521037f7e5ab23099885d373da9b9af701cffe06e62225f96f74be3ad6b5aeaad5b82ac6782012088a91429096c1c7a55cc968a98032fbff1cf5f3e98b1c68821037f7e5ab23099885d373da9b9af701cffe06e62225f96f74be3ad6b5aeaad5b82ac68ffffffff0000000000a91e1d00f0d8ffffffffffff000116b2c57a7bcb22e6240ddfd5764ba12bbe589748c8cab6d34d40b2699457a3cbf7bdf6ada43d7649508ecc22f6f6d54d693b6b7434138f8aced6386be251803cd1fb65e7eb2a876ee1d41d74939d398dcb9152e755587325d51ff94b548baf4cff7db34f02e1e419294d8b5ddd55996179da0096751585213b87211626cbf4e4fde3c62a7b40310b375101cbd15983b2b9034fa29293cd1733ee36ade06027005f3e41f93394f15918663b82165aad714fa5851b41f981c77dfdeecdb779472ca30979ec888d33c30fae0d702a2b5fb8a349b5c466338ecc8eef63cb76d04b2ff6ef3b83029f06f875ce0f825fad3538fa5aa3b9db54eaa4f81533ba68af227552707e82e8ad8331b8bb4ba3624a087c4b2ddbe08f21771a0eab22491e444ad663afbe53ec25d2bd9e75295e78b4e9642e65ba04ea4f307a7d3062c4ccf85a71251147abcdd28f7c900b5e8ff19a7d9e24846e9477e277db46f8510a42f8e4a966783818ee8c9fcfa4dc2b1cc7c97b69f8bbd32b5249411b3f0308626e7af28e44a06031e673340c092ec0af3c3b9250c7f00da03ba9634fc0b1a05833330cc1c1a1915ead0a81d62ec420b83936aeff8835100060b2d7e22f9bdb4c679ec38bc3946d66d139c721093902031b0657524736316927588f70817bd117bd757cb64f5cea95d21a5c629e6e784e5f1ea7afce150a4c2e07ab35cca2d8d242de12fc953f2642ffb13fd3e03e25bb7a3993d853263c4a565694554452ae28bf8cb1d83793c3fc6a78a7302b0941c233ba9da1febd5185527727ab3b53aff475408e41924b490f99e532cb24295e1053160077c41fb892695ced2cc73d6bbb18bbd4d0b4d48a3d2c3500c5bb472f404617d00704d0407e51b52284d82e03b901f3acaf99990645ac2ee3a895cc3521126385e3046152666c132c902ba34db629c076396dd6aab718b97bd453d6b7dd3c080528fef4e0482413d448b7f83d1966e10f0fe0fcc5315498abceb84a9e3a6b7ca2e3d0694a92a71c4f1b32fb950acaecbaa72aec501f0dfecb87684b40bbb5abdbc0ae21db978c9112424201c8b711c776c008b87753e9f512be610d594fde628b17bbdbc7dd0c06b479c991d8d7826231f6f0d13529b0ac4f9ae4203fe7fda84c290b120f38e0c0b0c427846a6c3beb7216100a049ba9f014b4fcd88a5a08866ca1e1f3f09f118a77a280486d50241260829de93e8fcd039e0a274767d4388b900e4a2ce4b592f0e416997d7660df0555dee05ddbd484d9f1512bffb683f2d01966b123140bf72c5631e81b73a1f857547ed736c3b2a1f1ac12eddb8d7c9855b523988b72ed0052789154fe244eec1166e557c546f590c0ecc6d8a6988f1f4bb09ba2347cafd2dc1c779c08bb132ddd56d54a339ef6b9dc0f0217fbeed4dcb721394290051e06"; + BitcoinyTransaction bitcoinyTransaction = PirateChain.deserializeRawTransaction(transactionDataHex); + assertEquals(1, bitcoinyTransaction.inputs.size()); + assertEquals(0, bitcoinyTransaction.outputs.size()); + assertEquals("47304402203929739d51dbc4b4d3435cf8b4930101601f670b3e8bcb23fde122b870385fba0220195aed5ed09b7dd342906c67c8da2896d00049bc75127c96724d03b7981fdbd80120baa6e68ffb2ddf19df6fce1b37d7e38b98f3706d5709e46d4f45f71c2e4bb7c301004c6b630436798662b17521037f7e5ab23099885d373da9b9af701cffe06e62225f96f74be3ad6b5aeaad5b82ac6782012088a91429096c1c7a55cc968a98032fbff1cf5f3e98b1c68821037f7e5ab23099885d373da9b9af701cffe06e62225f96f74be3ad6b5aeaad5b82ac68", bitcoinyTransaction.inputs.get(0).scriptSig); + assertEquals("efb7c5be4e870464795737109ed02b6c9b5e60e8676f68245c390b4cab09917e", bitcoinyTransaction.inputs.get(0).outputTxHash); + assertEquals(0, bitcoinyTransaction.inputs.get(0).outputVout); + assertEquals(-1, bitcoinyTransaction.inputs.get(0).sequence); + assertEquals(0, bitcoinyTransaction.locktime); + } + + @Test + public void testDecodeRawRefundTransaction() throws TransformationException { + String transactionDataHex = "0400008085202f8901a8eca1f787163374a2628d2db3521644392cb926770437eaf3fba0eec86f38fb00000000b8483045022100eb217ddf7c671f4d9d74f02b5d5a4340ec69e7e433d6fb839dc1aa0bf8a5059b02206b45f78df09a75ad151bb4bc91e5d555098ceace53cda938bb52ff0ad34dd4a40101514c6b630400738762b17521029ddc2860644ef2a3b6c7310432e2f4231f21171e26f04150363340cd17565ac8ac6782012088a914ab08c6bf2771e0b287303cc14cc02a6bd41a1fad8821029ddc2860644ef2a3b6c7310432e2f4231f21171e26f04150363340cd17565ac8ac68feffffff0000738762111f1d00f0d8ffffffffffff00012a22d50c89ad18ec56b09efb1ce5044c7ad9abcd378f935189168b96210b1e407ede37181c3b51841a78e786a3ba1ef87baac7d7408205a13ec95447e3409c5819f6bbfd31a80ba5d41d367410c5b106788b9e75c49c2916a755b324a10e9210579f97aa8267a490e5e80210e123e657007bf0810294bcc8d73f7cf1b8a1acf2d87edf5dfff0e61423a48fffac84c648bfebec3ff0fa97009ff3d945c6e895b7f5a1e09d50a7920b776b28f5e97dac3eeed25ec0f1ad3cd3ac9e0517fe3c03990fa5303e75b60522e8ffc3ef3493d4460fa14cd8019a96416519408806ee2afa891f1335b6dfd4d1590e9f7939b0718af4758f832d836b928bdfc9329741d906e935316e3d4ec3a24eaf4fc06c321b78bd524d09b4fe09242dd7280ff3f841b56375a6cffd9661db089d1ee6ba4f6e767da194bd4fcd21e860bfa84dd7f431381795ff5998c66b594cf4bfb78c80d044f02e26d9ec0b35e5968ffb98c9be2b196a8a9238116cbd343b3718025c43ae65bacbbc400fd65f957aee17ffb7322aa1dca016a30a5bf21bac910a509eecd54274113c0f24a34786dda9b364e71d1ae0872db8ba06c864cf02bffec15c62ac240de0507230f88679cb7b7c5555c08277840679f89a8ebc2ccc37cdaee5486857293eb2a227191193e03d073ad6a6293a400dabf1ef90215585b78efb6f970490a07382072a0000666b6b70cde068e8841ee4b695088f7a136b44947d03f6961e88d88f79e5e6d7e0b96b61b3d4cc07cd4666fc1e5385915083e0af96ca937320babe0ba43d7914ee501a021fcb6ac02a2232f976a9b123f54ceb1524fe718aa143c1f509bc297419b6cb5277cf16e105a857fd38ce33bc437b52628a8c5eb0f6a4022901f9efddd26c325aa2ad393dd3ec11a75be2884927a322207e7ff8bacb5cdf78503e2051ddac6d2a990471bb9b95e0e865b491d17ec9ee245f8800476f9c4d2475f0ee01561f29edd64dff3d0af2c5847dfcbd498aae3a4c6d497ff9cb359b326599928643567634ef68d3483d81ba364c47e2418c94aa6b70a8cf451f67ba78a194de9e297e1c9be62f2d580e1c3ecd301a3875fcd63fdbf8bb17d0d815c893590fabd76b0bd0f96ab2ff4e43aee4df2f8b07e8cd7342632b9c263dd57df083b96a95276f7576005f840b0d3d95f55f82425381ebaa6cdd64d943c1387695be4206ac749621514d30e460d0260f32c9493d3c35ab99ab5e166fc2b187600996406f96eb0d6c634a683138fcfa31fd028db05233d09c0cdd02a7737e70ebc2c5c5a42c0e9c7ab030020623e8c9d4807dbf8dde6224ca2f75c09aa08d3147d9761c00fa7012218ef325383d64ad35a61e37dc34aae5de1a233ae607c11094508eb39f4813025c4bd121492842b69182c288ec481d4e68ed9ce160e2b4f682e2ff6806"; + BitcoinyTransaction bitcoinyTransaction = PirateChain.deserializeRawTransaction(transactionDataHex); + assertEquals(1, bitcoinyTransaction.inputs.size()); + assertEquals(0, bitcoinyTransaction.outputs.size()); + assertEquals("483045022100eb217ddf7c671f4d9d74f02b5d5a4340ec69e7e433d6fb839dc1aa0bf8a5059b02206b45f78df09a75ad151bb4bc91e5d555098ceace53cda938bb52ff0ad34dd4a40101514c6b630400738762b17521029ddc2860644ef2a3b6c7310432e2f4231f21171e26f04150363340cd17565ac8ac6782012088a914ab08c6bf2771e0b287303cc14cc02a6bd41a1fad8821029ddc2860644ef2a3b6c7310432e2f4231f21171e26f04150363340cd17565ac8ac68", bitcoinyTransaction.inputs.get(0).scriptSig); + assertEquals("a8eca1f787163374a2628d2db3521644392cb926770437eaf3fba0eec86f38fb", bitcoinyTransaction.inputs.get(0).outputTxHash); + assertEquals(0, bitcoinyTransaction.inputs.get(0).outputVout); + assertEquals(-2, bitcoinyTransaction.inputs.get(0).sequence); + assertEquals(1653043968, bitcoinyTransaction.locktime); + } + + @Test + @Ignore(value = "Doesn't work, to be fixed later") + public void testFindHtlcSecret() throws ForeignBlockchainException { + // This actually exists on TEST3 but can take a while to fetch + String p2shAddress = "2N8WCg52ULCtDSMjkgVTm5mtPdCsUptkHWE"; + + byte[] expectedSecret = "This string is exactly 32 bytes!".getBytes(); + byte[] secret = BitcoinyHTLC.findHtlcSecret(pirateChain, p2shAddress); + + assertNotNull("secret not found", secret); + assertTrue("secret incorrect", Arrays.equals(expectedSecret, secret)); + } + + @Test + @Ignore(value = "Needs adapting for Pirate Chain") + public void testBuildSpend() { + String xprv58 = "tprv8ZgxMBicQKsPdahhFSrCdvC1bsWyzHHZfTneTVqUXN6s1wEtZLwAkZXzFP6TYLg2aQMecZLXLre5bTVGajEB55L1HYJcawpdFG66STVAWPJ"; + + String recipient = "2N8WCg52ULCtDSMjkgVTm5mtPdCsUptkHWE"; + long amount = 1000L; + + Transaction transaction = pirateChain.buildSpend(xprv58, recipient, amount); + assertNotNull("insufficient funds", transaction); + + // Check spent key caching doesn't affect outcome + + transaction = pirateChain.buildSpend(xprv58, recipient, amount); + assertNotNull("insufficient funds", transaction); + } + + @Test + @Ignore(value = "Needs adapting for Pirate Chain") + public void testGetWalletBalance() throws ForeignBlockchainException { + String xprv58 = "tprv8ZgxMBicQKsPdahhFSrCdvC1bsWyzHHZfTneTVqUXN6s1wEtZLwAkZXzFP6TYLg2aQMecZLXLre5bTVGajEB55L1HYJcawpdFG66STVAWPJ"; + + Long balance = pirateChain.getWalletBalance(xprv58); + + assertNotNull(balance); + + System.out.println(pirateChain.format(balance)); + + // Check spent key caching doesn't affect outcome + + Long repeatBalance = pirateChain.getWalletBalance(xprv58); + + assertNotNull(repeatBalance); + + System.out.println(pirateChain.format(repeatBalance)); + + assertEquals(balance, repeatBalance); + } + + @Test + @Ignore(value = "Needs adapting for Pirate Chain") + public void testGetUnusedReceiveAddress() throws ForeignBlockchainException { + String xprv58 = "tprv8ZgxMBicQKsPdahhFSrCdvC1bsWyzHHZfTneTVqUXN6s1wEtZLwAkZXzFP6TYLg2aQMecZLXLre5bTVGajEB55L1HYJcawpdFG66STVAWPJ"; + + String address = pirateChain.getUnusedReceiveAddress(xprv58); + + assertNotNull(address); + + System.out.println(address); + } + +} diff --git a/src/test/java/org/qortal/test/crosschain/RavencoinTests.java b/src/test/java/org/qortal/test/crosschain/RavencoinTests.java index afcbfe95..866c41a2 100644 --- a/src/test/java/org/qortal/test/crosschain/RavencoinTests.java +++ b/src/test/java/org/qortal/test/crosschain/RavencoinTests.java @@ -81,7 +81,7 @@ public class RavencoinTests extends Common { } @Test - public void testGetWalletBalance() { + public void testGetWalletBalance() throws ForeignBlockchainException { String xprv58 = "xpub661MyMwAqRbcEt3Ge1wNmkagyb1J7yTQu4Kquvy77Ycg2iPoh7Urg8s9Jdwp7YmrqGkDKJpUVjsZXSSsQgmAVUC17ZVQQeoWMzm7vDTt1y7"; Long balance = ravencoin.getWalletBalance(xprv58); diff --git a/src/test/java/org/qortal/test/crosschain/piratechainv3/PirateChainACCTv3Tests.java b/src/test/java/org/qortal/test/crosschain/piratechainv3/PirateChainACCTv3Tests.java new file mode 100644 index 00000000..f9ac9de1 --- /dev/null +++ b/src/test/java/org/qortal/test/crosschain/piratechainv3/PirateChainACCTv3Tests.java @@ -0,0 +1,771 @@ +package org.qortal.test.crosschain.piratechainv3; + +import com.google.common.hash.HashCode; +import com.google.common.primitives.Bytes; +import org.junit.Before; +import org.junit.Test; +import org.qortal.account.Account; +import org.qortal.account.PrivateKeyAccount; +import org.qortal.asset.Asset; +import org.qortal.block.Block; +import org.qortal.crosschain.AcctMode; +import org.qortal.crosschain.PirateChainACCTv3; +import org.qortal.crypto.Crypto; +import org.qortal.data.at.ATData; +import org.qortal.data.at.ATStateData; +import org.qortal.data.crosschain.CrossChainTradeData; +import org.qortal.data.transaction.BaseTransactionData; +import org.qortal.data.transaction.DeployAtTransactionData; +import org.qortal.data.transaction.MessageTransactionData; +import org.qortal.data.transaction.TransactionData; +import org.qortal.group.Group; +import org.qortal.repository.DataException; +import org.qortal.repository.Repository; +import org.qortal.repository.RepositoryManager; +import org.qortal.test.common.BlockUtils; +import org.qortal.test.common.Common; +import org.qortal.test.common.TransactionUtils; +import org.qortal.transaction.DeployAtTransaction; +import org.qortal.transaction.MessageTransaction; +import org.qortal.utils.Amounts; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.time.format.FormatStyle; +import java.util.Arrays; +import java.util.List; +import java.util.Random; +import java.util.function.Function; + +import static org.junit.Assert.*; + +public class PirateChainACCTv3Tests extends Common { + + public static final byte[] secretA = "This string is exactly 32 bytes!".getBytes(); + public static final byte[] hashOfSecretA = Crypto.hash160(secretA); // daf59884b4d1aec8c1b17102530909ee43c0151a + public static final byte[] pirateChainPublicKey = HashCode.fromString("aabb00bb11bb22bb33bb44bb55bb66bb77bb88bb99cc00cc11cc22cc33cc44cc55").asBytes(); // 33 bytes + public static final int tradeTimeout = 20; // blocks + public static final long redeemAmount = 80_40200000L; + public static final long fundingAmount = 123_45600000L; + public static final long arrrAmount = 864200L; // 0.00864200 ARRR + + private static final Random RANDOM = new Random(); + + @Before + public void beforeTest() throws DataException { + Common.useDefaultSettings(); + } + + @Test + public void testCompile() { + PrivateKeyAccount tradeAccount = createTradeAccount(null); + + byte[] creationBytes = PirateChainACCTv3.buildQortalAT(tradeAccount.getAddress(), pirateChainPublicKey, redeemAmount, arrrAmount, tradeTimeout); + assertNotNull(creationBytes); + + System.out.println("AT creation bytes: " + HashCode.fromBytes(creationBytes).toString()); + } + + @Test + public void testDeploy() throws DataException { + try (final Repository repository = RepositoryManager.getRepository()) { + PrivateKeyAccount deployer = Common.getTestAccount(repository, "chloe"); + PrivateKeyAccount tradeAccount = createTradeAccount(repository); + + PrivateKeyAccount partner = Common.getTestAccount(repository, "dilbert"); + + long deployersInitialBalance = deployer.getConfirmedBalance(Asset.QORT); + long partnersInitialBalance = partner.getConfirmedBalance(Asset.QORT); + + DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer, tradeAccount.getAddress()); + + long expectedBalance = deployersInitialBalance - fundingAmount - deployAtTransaction.getTransactionData().getFee(); + long actualBalance = deployer.getConfirmedBalance(Asset.QORT); + + assertEquals("Deployer's post-deployment balance incorrect", expectedBalance, actualBalance); + + expectedBalance = fundingAmount; + actualBalance = deployAtTransaction.getATAccount().getConfirmedBalance(Asset.QORT); + + assertEquals("AT's post-deployment balance incorrect", expectedBalance, actualBalance); + + expectedBalance = partnersInitialBalance; + actualBalance = partner.getConfirmedBalance(Asset.QORT); + + assertEquals("Partner's post-deployment balance incorrect", expectedBalance, actualBalance); + + // Test orphaning + BlockUtils.orphanLastBlock(repository); + + expectedBalance = deployersInitialBalance; + actualBalance = deployer.getConfirmedBalance(Asset.QORT); + + assertEquals("Deployer's post-orphan/pre-deployment balance incorrect", expectedBalance, actualBalance); + + expectedBalance = 0; + actualBalance = deployAtTransaction.getATAccount().getConfirmedBalance(Asset.QORT); + + assertEquals("AT's post-orphan/pre-deployment balance incorrect", expectedBalance, actualBalance); + + expectedBalance = partnersInitialBalance; + actualBalance = partner.getConfirmedBalance(Asset.QORT); + + assertEquals("Partner's post-orphan/pre-deployment balance incorrect", expectedBalance, actualBalance); + } + } + + @SuppressWarnings("unused") + @Test + public void testOfferCancel() throws DataException { + try (final Repository repository = RepositoryManager.getRepository()) { + PrivateKeyAccount deployer = Common.getTestAccount(repository, "chloe"); + PrivateKeyAccount tradeAccount = createTradeAccount(repository); + + PrivateKeyAccount partner = Common.getTestAccount(repository, "dilbert"); + + long deployersInitialBalance = deployer.getConfirmedBalance(Asset.QORT); + long partnersInitialBalance = partner.getConfirmedBalance(Asset.QORT); + + DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer, tradeAccount.getAddress()); + Account at = deployAtTransaction.getATAccount(); + String atAddress = at.getAddress(); + + long deployAtFee = deployAtTransaction.getTransactionData().getFee(); + long deployersPostDeploymentBalance = deployersInitialBalance - fundingAmount - deployAtFee; + + // Send creator's address to AT, instead of typical partner's address + byte[] messageData = PirateChainACCTv3.getInstance().buildCancelMessage(deployer.getAddress()); + MessageTransaction messageTransaction = sendMessage(repository, deployer, messageData, atAddress); + long messageFee = messageTransaction.getTransactionData().getFee(); + + // AT should process 'cancel' message in next block + BlockUtils.mintBlock(repository); + + describeAt(repository, atAddress); + + // Check AT is finished + ATData atData = repository.getATRepository().fromATAddress(atAddress); + assertTrue(atData.getIsFinished()); + + // AT should be in CANCELLED mode + CrossChainTradeData tradeData = PirateChainACCTv3.getInstance().populateTradeData(repository, atData); + assertEquals(AcctMode.CANCELLED, tradeData.mode); + + // Check balances + long expectedMinimumBalance = deployersPostDeploymentBalance; + long expectedMaximumBalance = deployersInitialBalance - deployAtFee - messageFee; + + long actualBalance = deployer.getConfirmedBalance(Asset.QORT); + + assertTrue(String.format("Deployer's balance %s should be above minimum %s", actualBalance, expectedMinimumBalance), actualBalance > expectedMinimumBalance); + assertTrue(String.format("Deployer's balance %s should be below maximum %s", actualBalance, expectedMaximumBalance), actualBalance < expectedMaximumBalance); + + // Test orphaning + BlockUtils.orphanLastBlock(repository); + + // Check balances + long expectedBalance = deployersPostDeploymentBalance - messageFee; + actualBalance = deployer.getConfirmedBalance(Asset.QORT); + + assertEquals("Deployer's post-orphan/pre-refund balance incorrect", expectedBalance, actualBalance); + } + } + + @SuppressWarnings("unused") + @Test + public void testOfferCancelInvalidLength() throws DataException { + try (final Repository repository = RepositoryManager.getRepository()) { + PrivateKeyAccount deployer = Common.getTestAccount(repository, "chloe"); + PrivateKeyAccount tradeAccount = createTradeAccount(repository); + + PrivateKeyAccount partner = Common.getTestAccount(repository, "dilbert"); + + long deployersInitialBalance = deployer.getConfirmedBalance(Asset.QORT); + long partnersInitialBalance = partner.getConfirmedBalance(Asset.QORT); + + DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer, tradeAccount.getAddress()); + Account at = deployAtTransaction.getATAccount(); + String atAddress = at.getAddress(); + + long deployAtFee = deployAtTransaction.getTransactionData().getFee(); + long deployersPostDeploymentBalance = deployersInitialBalance - fundingAmount - deployAtFee; + + // Instead of sending creator's address to AT, send too-short/invalid message + byte[] messageData = new byte[7]; + RANDOM.nextBytes(messageData); + MessageTransaction messageTransaction = sendMessage(repository, deployer, messageData, atAddress); + long messageFee = messageTransaction.getTransactionData().getFee(); + + // AT should process 'cancel' message in next block + // As message is too short, it will be padded to 32bytes but cancel code doesn't care about message content, so should be ok + BlockUtils.mintBlock(repository); + + describeAt(repository, atAddress); + + // Check AT is finished + ATData atData = repository.getATRepository().fromATAddress(atAddress); + assertTrue(atData.getIsFinished()); + + // AT should be in CANCELLED mode + CrossChainTradeData tradeData = PirateChainACCTv3.getInstance().populateTradeData(repository, atData); + assertEquals(AcctMode.CANCELLED, tradeData.mode); + } + } + + @SuppressWarnings("unused") + @Test + public void testTradingInfoProcessing() throws DataException { + try (final Repository repository = RepositoryManager.getRepository()) { + PrivateKeyAccount deployer = Common.getTestAccount(repository, "chloe"); + PrivateKeyAccount tradeAccount = createTradeAccount(repository); + + PrivateKeyAccount partner = Common.getTestAccount(repository, "dilbert"); + + long deployersInitialBalance = deployer.getConfirmedBalance(Asset.QORT); + long partnersInitialBalance = partner.getConfirmedBalance(Asset.QORT); + + DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer, tradeAccount.getAddress()); + Account at = deployAtTransaction.getATAccount(); + String atAddress = at.getAddress(); + + long partnersOfferMessageTransactionTimestamp = System.currentTimeMillis(); + int lockTimeA = calcTestLockTimeA(partnersOfferMessageTransactionTimestamp); + int refundTimeout = PirateChainACCTv3.calcRefundTimeout(partnersOfferMessageTransactionTimestamp, lockTimeA); + + // Send trade info to AT + byte[] messageData = PirateChainACCTv3.buildTradeMessage(partner.getAddress(), pirateChainPublicKey, hashOfSecretA, lockTimeA, refundTimeout); + MessageTransaction messageTransaction = sendMessage(repository, tradeAccount, messageData, atAddress); + + Block postDeploymentBlock = BlockUtils.mintBlock(repository); + int postDeploymentBlockHeight = postDeploymentBlock.getBlockData().getHeight(); + + long deployAtFee = deployAtTransaction.getTransactionData().getFee(); + long deployersPostDeploymentBalance = deployersInitialBalance - fundingAmount - deployAtFee; + + describeAt(repository, atAddress); + + System.out.println(String.format("pirateChainPublicKey: %s", HashCode.fromBytes(pirateChainPublicKey))); + + ATData atData = repository.getATRepository().fromATAddress(atAddress); + CrossChainTradeData tradeData = PirateChainACCTv3.getInstance().populateTradeData(repository, atData); + + // AT should be in TRADE mode + assertEquals(AcctMode.TRADING, tradeData.mode); + + // Check hashOfSecretA was extracted correctly + assertTrue(Arrays.equals(hashOfSecretA, tradeData.hashOfSecretA)); + + // Check trade partner Qortal address was extracted correctly + assertEquals(partner.getAddress(), tradeData.qortalPartnerAddress); + + // Check trade partner's Litecoin PKH was extracted correctly + assertTrue(Arrays.equals(pirateChainPublicKey, tradeData.partnerForeignPKH)); + + // Test orphaning + BlockUtils.orphanToBlock(repository, postDeploymentBlockHeight); + + // Check balances + long expectedBalance = deployersPostDeploymentBalance; + long actualBalance = deployer.getConfirmedBalance(Asset.QORT); + + assertEquals("Deployer's post-orphan/pre-refund balance incorrect", expectedBalance, actualBalance); + } + } + + // TEST SENDING TRADING INFO BUT NOT FROM AT CREATOR (SHOULD BE IGNORED) + @SuppressWarnings("unused") + @Test + public void testIncorrectTradeSender() throws DataException { + try (final Repository repository = RepositoryManager.getRepository()) { + PrivateKeyAccount deployer = Common.getTestAccount(repository, "chloe"); + PrivateKeyAccount tradeAccount = createTradeAccount(repository); + + PrivateKeyAccount partner = Common.getTestAccount(repository, "dilbert"); + + PrivateKeyAccount bystander = Common.getTestAccount(repository, "bob"); + + long deployersInitialBalance = deployer.getConfirmedBalance(Asset.QORT); + long partnersInitialBalance = partner.getConfirmedBalance(Asset.QORT); + + DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer, tradeAccount.getAddress()); + Account at = deployAtTransaction.getATAccount(); + String atAddress = at.getAddress(); + + long partnersOfferMessageTransactionTimestamp = System.currentTimeMillis(); + int lockTimeA = calcTestLockTimeA(partnersOfferMessageTransactionTimestamp); + int refundTimeout = PirateChainACCTv3.calcRefundTimeout(partnersOfferMessageTransactionTimestamp, lockTimeA); + + // Send trade info to AT BUT NOT FROM AT CREATOR + byte[] messageData = PirateChainACCTv3.buildTradeMessage(partner.getAddress(), pirateChainPublicKey, hashOfSecretA, lockTimeA, refundTimeout); + MessageTransaction messageTransaction = sendMessage(repository, bystander, messageData, atAddress); + + BlockUtils.mintBlock(repository); + + long expectedBalance = partnersInitialBalance; + long actualBalance = partner.getConfirmedBalance(Asset.QORT); + + assertEquals("Partner's post-initial-payout balance incorrect", expectedBalance, actualBalance); + + describeAt(repository, atAddress); + + ATData atData = repository.getATRepository().fromATAddress(atAddress); + CrossChainTradeData tradeData = PirateChainACCTv3.getInstance().populateTradeData(repository, atData); + + // AT should still be in OFFER mode + assertEquals(AcctMode.OFFERING, tradeData.mode); + } + } + + @SuppressWarnings("unused") + @Test + public void testAutomaticTradeRefund() throws DataException { + try (final Repository repository = RepositoryManager.getRepository()) { + PrivateKeyAccount deployer = Common.getTestAccount(repository, "chloe"); + PrivateKeyAccount tradeAccount = createTradeAccount(repository); + + PrivateKeyAccount partner = Common.getTestAccount(repository, "dilbert"); + + long deployersInitialBalance = deployer.getConfirmedBalance(Asset.QORT); + long partnersInitialBalance = partner.getConfirmedBalance(Asset.QORT); + + DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer, tradeAccount.getAddress()); + Account at = deployAtTransaction.getATAccount(); + String atAddress = at.getAddress(); + + long partnersOfferMessageTransactionTimestamp = System.currentTimeMillis(); + int lockTimeA = calcTestLockTimeA(partnersOfferMessageTransactionTimestamp); + int refundTimeout = PirateChainACCTv3.calcRefundTimeout(partnersOfferMessageTransactionTimestamp, lockTimeA); + + // Send trade info to AT + byte[] messageData = PirateChainACCTv3.buildTradeMessage(partner.getAddress(), pirateChainPublicKey, hashOfSecretA, lockTimeA, refundTimeout); + MessageTransaction messageTransaction = sendMessage(repository, tradeAccount, messageData, atAddress); + + Block postDeploymentBlock = BlockUtils.mintBlock(repository); + int postDeploymentBlockHeight = postDeploymentBlock.getBlockData().getHeight(); + + // Check refund + long deployAtFee = deployAtTransaction.getTransactionData().getFee(); + long deployersPostDeploymentBalance = deployersInitialBalance - fundingAmount - deployAtFee; + + checkTradeRefund(repository, deployer, deployersInitialBalance, deployAtFee); + + describeAt(repository, atAddress); + + // Check AT is finished + ATData atData = repository.getATRepository().fromATAddress(atAddress); + assertTrue(atData.getIsFinished()); + + // AT should be in REFUNDED mode + CrossChainTradeData tradeData = PirateChainACCTv3.getInstance().populateTradeData(repository, atData); + assertEquals(AcctMode.REFUNDED, tradeData.mode); + + // Test orphaning + BlockUtils.orphanToBlock(repository, postDeploymentBlockHeight); + + // Check balances + long expectedBalance = deployersPostDeploymentBalance; + long actualBalance = deployer.getConfirmedBalance(Asset.QORT); + + assertEquals("Deployer's post-orphan/pre-refund balance incorrect", expectedBalance, actualBalance); + } + } + + @SuppressWarnings("unused") + @Test + public void testCorrectSecretCorrectSender() throws DataException { + try (final Repository repository = RepositoryManager.getRepository()) { + PrivateKeyAccount deployer = Common.getTestAccount(repository, "chloe"); + PrivateKeyAccount tradeAccount = createTradeAccount(repository); + + PrivateKeyAccount partner = Common.getTestAccount(repository, "dilbert"); + + long deployersInitialBalance = deployer.getConfirmedBalance(Asset.QORT); + long partnersInitialBalance = partner.getConfirmedBalance(Asset.QORT); + + DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer, tradeAccount.getAddress()); + Account at = deployAtTransaction.getATAccount(); + String atAddress = at.getAddress(); + + long partnersOfferMessageTransactionTimestamp = System.currentTimeMillis(); + int lockTimeA = calcTestLockTimeA(partnersOfferMessageTransactionTimestamp); + int refundTimeout = PirateChainACCTv3.calcRefundTimeout(partnersOfferMessageTransactionTimestamp, lockTimeA); + + // Send trade info to AT + byte[] messageData = PirateChainACCTv3.buildTradeMessage(partner.getAddress(), pirateChainPublicKey, hashOfSecretA, lockTimeA, refundTimeout); + MessageTransaction messageTransaction = sendMessage(repository, tradeAccount, messageData, atAddress); + + // Give AT time to process message + BlockUtils.mintBlock(repository); + + // Send correct secret to AT, from correct account + messageData = PirateChainACCTv3.buildRedeemMessage(secretA, partner.getAddress()); + messageTransaction = sendMessage(repository, partner, messageData, atAddress); + + // AT should send funds in the next block + ATStateData preRedeemAtStateData = repository.getATRepository().getLatestATState(atAddress); + BlockUtils.mintBlock(repository); + + describeAt(repository, atAddress); + + // Check AT is finished + ATData atData = repository.getATRepository().fromATAddress(atAddress); + assertTrue(atData.getIsFinished()); + + // AT should be in REDEEMED mode + CrossChainTradeData tradeData = PirateChainACCTv3.getInstance().populateTradeData(repository, atData); + assertEquals(AcctMode.REDEEMED, tradeData.mode); + + // Check balances + long expectedBalance = partnersInitialBalance - messageTransaction.getTransactionData().getFee() + redeemAmount; + long actualBalance = partner.getConfirmedBalance(Asset.QORT); + + assertEquals("Partner's post-redeem balance incorrect", expectedBalance, actualBalance); + + // Orphan redeem + BlockUtils.orphanLastBlock(repository); + + // Check balances + expectedBalance = partnersInitialBalance - messageTransaction.getTransactionData().getFee(); + actualBalance = partner.getConfirmedBalance(Asset.QORT); + + assertEquals("Partner's post-orphan/pre-redeem balance incorrect", expectedBalance, actualBalance); + + // Check AT state + ATStateData postOrphanAtStateData = repository.getATRepository().getLatestATState(atAddress); + + assertTrue("AT states mismatch", Arrays.equals(preRedeemAtStateData.getStateData(), postOrphanAtStateData.getStateData())); + } + } + + @SuppressWarnings("unused") + @Test + public void testCorrectSecretIncorrectSender() throws DataException { + try (final Repository repository = RepositoryManager.getRepository()) { + PrivateKeyAccount deployer = Common.getTestAccount(repository, "chloe"); + PrivateKeyAccount tradeAccount = createTradeAccount(repository); + + PrivateKeyAccount partner = Common.getTestAccount(repository, "dilbert"); + + PrivateKeyAccount bystander = Common.getTestAccount(repository, "bob"); + + long deployersInitialBalance = deployer.getConfirmedBalance(Asset.QORT); + long partnersInitialBalance = partner.getConfirmedBalance(Asset.QORT); + + DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer, tradeAccount.getAddress()); + long deployAtFee = deployAtTransaction.getTransactionData().getFee(); + + Account at = deployAtTransaction.getATAccount(); + String atAddress = at.getAddress(); + + long partnersOfferMessageTransactionTimestamp = System.currentTimeMillis(); + int lockTimeA = calcTestLockTimeA(partnersOfferMessageTransactionTimestamp); + int refundTimeout = PirateChainACCTv3.calcRefundTimeout(partnersOfferMessageTransactionTimestamp, lockTimeA); + + // Send trade info to AT + byte[] messageData = PirateChainACCTv3.buildTradeMessage(partner.getAddress(), pirateChainPublicKey, hashOfSecretA, lockTimeA, refundTimeout); + MessageTransaction messageTransaction = sendMessage(repository, tradeAccount, messageData, atAddress); + + // Give AT time to process message + BlockUtils.mintBlock(repository); + + // Send correct secret to AT, but from wrong account + messageData = PirateChainACCTv3.buildRedeemMessage(secretA, partner.getAddress()); + messageTransaction = sendMessage(repository, bystander, messageData, atAddress); + + // AT should NOT send funds in the next block + ATStateData preRedeemAtStateData = repository.getATRepository().getLatestATState(atAddress); + BlockUtils.mintBlock(repository); + + describeAt(repository, atAddress); + + // Check AT is NOT finished + ATData atData = repository.getATRepository().fromATAddress(atAddress); + assertFalse(atData.getIsFinished()); + + // AT should still be in TRADE mode + CrossChainTradeData tradeData = PirateChainACCTv3.getInstance().populateTradeData(repository, atData); + assertEquals(AcctMode.TRADING, tradeData.mode); + + // Check balances + long expectedBalance = partnersInitialBalance; + long actualBalance = partner.getConfirmedBalance(Asset.QORT); + + assertEquals("Partner's balance incorrect", expectedBalance, actualBalance); + + // Check eventual refund + checkTradeRefund(repository, deployer, deployersInitialBalance, deployAtFee); + } + } + + @SuppressWarnings("unused") + @Test + public void testIncorrectSecretCorrectSender() throws DataException { + try (final Repository repository = RepositoryManager.getRepository()) { + PrivateKeyAccount deployer = Common.getTestAccount(repository, "chloe"); + PrivateKeyAccount tradeAccount = createTradeAccount(repository); + + PrivateKeyAccount partner = Common.getTestAccount(repository, "dilbert"); + + long deployersInitialBalance = deployer.getConfirmedBalance(Asset.QORT); + long partnersInitialBalance = partner.getConfirmedBalance(Asset.QORT); + + DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer, tradeAccount.getAddress()); + long deployAtFee = deployAtTransaction.getTransactionData().getFee(); + + Account at = deployAtTransaction.getATAccount(); + String atAddress = at.getAddress(); + + long partnersOfferMessageTransactionTimestamp = System.currentTimeMillis(); + int lockTimeA = calcTestLockTimeA(partnersOfferMessageTransactionTimestamp); + int refundTimeout = PirateChainACCTv3.calcRefundTimeout(partnersOfferMessageTransactionTimestamp, lockTimeA); + + // Send trade info to AT + byte[] messageData = PirateChainACCTv3.buildTradeMessage(partner.getAddress(), pirateChainPublicKey, hashOfSecretA, lockTimeA, refundTimeout); + MessageTransaction messageTransaction = sendMessage(repository, tradeAccount, messageData, atAddress); + + // Give AT time to process message + BlockUtils.mintBlock(repository); + + // Send incorrect secret to AT, from correct account + byte[] wrongSecret = new byte[32]; + RANDOM.nextBytes(wrongSecret); + messageData = PirateChainACCTv3.buildRedeemMessage(wrongSecret, partner.getAddress()); + messageTransaction = sendMessage(repository, partner, messageData, atAddress); + + // AT should NOT send funds in the next block + ATStateData preRedeemAtStateData = repository.getATRepository().getLatestATState(atAddress); + BlockUtils.mintBlock(repository); + + describeAt(repository, atAddress); + + // Check AT is NOT finished + ATData atData = repository.getATRepository().fromATAddress(atAddress); + assertFalse(atData.getIsFinished()); + + // AT should still be in TRADE mode + CrossChainTradeData tradeData = PirateChainACCTv3.getInstance().populateTradeData(repository, atData); + assertEquals(AcctMode.TRADING, tradeData.mode); + + long expectedBalance = partnersInitialBalance - messageTransaction.getTransactionData().getFee(); + long actualBalance = partner.getConfirmedBalance(Asset.QORT); + + assertEquals("Partner's balance incorrect", expectedBalance, actualBalance); + + // Check eventual refund + checkTradeRefund(repository, deployer, deployersInitialBalance, deployAtFee); + } + } + + @SuppressWarnings("unused") + @Test + public void testCorrectSecretCorrectSenderInvalidMessageLength() throws DataException { + try (final Repository repository = RepositoryManager.getRepository()) { + PrivateKeyAccount deployer = Common.getTestAccount(repository, "chloe"); + PrivateKeyAccount tradeAccount = createTradeAccount(repository); + + PrivateKeyAccount partner = Common.getTestAccount(repository, "dilbert"); + + long deployersInitialBalance = deployer.getConfirmedBalance(Asset.QORT); + long partnersInitialBalance = partner.getConfirmedBalance(Asset.QORT); + + DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer, tradeAccount.getAddress()); + Account at = deployAtTransaction.getATAccount(); + String atAddress = at.getAddress(); + + long partnersOfferMessageTransactionTimestamp = System.currentTimeMillis(); + int lockTimeA = calcTestLockTimeA(partnersOfferMessageTransactionTimestamp); + int refundTimeout = PirateChainACCTv3.calcRefundTimeout(partnersOfferMessageTransactionTimestamp, lockTimeA); + + // Send trade info to AT + byte[] messageData = PirateChainACCTv3.buildTradeMessage(partner.getAddress(), pirateChainPublicKey, hashOfSecretA, lockTimeA, refundTimeout); + MessageTransaction messageTransaction = sendMessage(repository, tradeAccount, messageData, atAddress); + + // Give AT time to process message + BlockUtils.mintBlock(repository); + + // Send correct secret to AT, from correct account, but missing receive address, hence incorrect length + messageData = Bytes.concat(secretA); + messageTransaction = sendMessage(repository, partner, messageData, atAddress); + + // AT should NOT send funds in the next block + ATStateData preRedeemAtStateData = repository.getATRepository().getLatestATState(atAddress); + BlockUtils.mintBlock(repository); + + describeAt(repository, atAddress); + + // Check AT is NOT finished + ATData atData = repository.getATRepository().fromATAddress(atAddress); + assertFalse(atData.getIsFinished()); + + // AT should be in TRADING mode + CrossChainTradeData tradeData = PirateChainACCTv3.getInstance().populateTradeData(repository, atData); + assertEquals(AcctMode.TRADING, tradeData.mode); + } + } + + @SuppressWarnings("unused") + @Test + public void testDescribeDeployed() throws DataException { + try (final Repository repository = RepositoryManager.getRepository()) { + PrivateKeyAccount deployer = Common.getTestAccount(repository, "chloe"); + PrivateKeyAccount tradeAccount = createTradeAccount(repository); + + PrivateKeyAccount partner = Common.getTestAccount(repository, "dilbert"); + + long deployersInitialBalance = deployer.getConfirmedBalance(Asset.QORT); + long partnersInitialBalance = partner.getConfirmedBalance(Asset.QORT); + + DeployAtTransaction deployAtTransaction = doDeploy(repository, deployer, tradeAccount.getAddress()); + + List executableAts = repository.getATRepository().getAllExecutableATs(); + + for (ATData atData : executableAts) { + String atAddress = atData.getATAddress(); + byte[] codeBytes = atData.getCodeBytes(); + byte[] codeHash = Crypto.digest(codeBytes); + + System.out.println(String.format("%s: code length: %d byte%s, code hash: %s", + atAddress, + codeBytes.length, + (codeBytes.length != 1 ? "s": ""), + HashCode.fromBytes(codeHash))); + + // Not one of ours? + if (!Arrays.equals(codeHash, PirateChainACCTv3.CODE_BYTES_HASH)) + continue; + + describeAt(repository, atAddress); + } + } + } + + private int calcTestLockTimeA(long messageTimestamp) { + return (int) (messageTimestamp / 1000L + tradeTimeout * 60); + } + + private DeployAtTransaction doDeploy(Repository repository, PrivateKeyAccount deployer, String tradeAddress) throws DataException { + byte[] creationBytes = PirateChainACCTv3.buildQortalAT(tradeAddress, pirateChainPublicKey, redeemAmount, arrrAmount, tradeTimeout); + + long txTimestamp = System.currentTimeMillis(); + byte[] lastReference = deployer.getLastReference(); + + if (lastReference == null) { + System.err.println(String.format("Qortal account %s has no last reference", deployer.getAddress())); + System.exit(2); + } + + Long fee = null; + String name = "QORT-ARRR cross-chain trade"; + String description = String.format("Qortal-PirateChain cross-chain trade"); + String atType = "ACCT"; + String tags = "QORT-ARRR ACCT"; + + BaseTransactionData baseTransactionData = new BaseTransactionData(txTimestamp, Group.NO_GROUP, lastReference, deployer.getPublicKey(), fee, null); + TransactionData deployAtTransactionData = new DeployAtTransactionData(baseTransactionData, name, description, atType, tags, creationBytes, fundingAmount, Asset.QORT); + + DeployAtTransaction deployAtTransaction = new DeployAtTransaction(repository, deployAtTransactionData); + + fee = deployAtTransaction.calcRecommendedFee(); + deployAtTransactionData.setFee(fee); + + TransactionUtils.signAndMint(repository, deployAtTransactionData, deployer); + + return deployAtTransaction; + } + + private MessageTransaction sendMessage(Repository repository, PrivateKeyAccount sender, byte[] data, String recipient) throws DataException { + long txTimestamp = System.currentTimeMillis(); + byte[] lastReference = sender.getLastReference(); + + if (lastReference == null) { + System.err.println(String.format("Qortal account %s has no last reference", sender.getAddress())); + System.exit(2); + } + + Long fee = null; + int version = 4; + int nonce = 0; + long amount = 0; + Long assetId = null; // because amount is zero + + BaseTransactionData baseTransactionData = new BaseTransactionData(txTimestamp, Group.NO_GROUP, lastReference, sender.getPublicKey(), fee, null); + TransactionData messageTransactionData = new MessageTransactionData(baseTransactionData, version, nonce, recipient, amount, assetId, data, false, false); + + MessageTransaction messageTransaction = new MessageTransaction(repository, messageTransactionData); + + fee = messageTransaction.calcRecommendedFee(); + messageTransactionData.setFee(fee); + + TransactionUtils.signAndMint(repository, messageTransactionData, sender); + + return messageTransaction; + } + + private void checkTradeRefund(Repository repository, Account deployer, long deployersInitialBalance, long deployAtFee) throws DataException { + long deployersPostDeploymentBalance = deployersInitialBalance - fundingAmount - deployAtFee; + int refundTimeout = tradeTimeout / 2 + 1; // close enough + + // AT should automatically refund deployer after 'refundTimeout' blocks + for (int blockCount = 0; blockCount <= refundTimeout; ++blockCount) + BlockUtils.mintBlock(repository); + + // We don't bother to exactly calculate QORT spent running AT for several blocks, but we do know the expected range + long expectedMinimumBalance = deployersPostDeploymentBalance; + long expectedMaximumBalance = deployersInitialBalance - deployAtFee; + + long actualBalance = deployer.getConfirmedBalance(Asset.QORT); + + assertTrue(String.format("Deployer's balance %s should be above minimum %s", actualBalance, expectedMinimumBalance), actualBalance > expectedMinimumBalance); + assertTrue(String.format("Deployer's balance %s should be below maximum %s", actualBalance, expectedMaximumBalance), actualBalance < expectedMaximumBalance); + } + + private void describeAt(Repository repository, String atAddress) throws DataException { + ATData atData = repository.getATRepository().fromATAddress(atAddress); + CrossChainTradeData tradeData = PirateChainACCTv3.getInstance().populateTradeData(repository, atData); + + Function epochMilliFormatter = (timestamp) -> LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneOffset.UTC).format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)); + int currentBlockHeight = repository.getBlockRepository().getBlockchainHeight(); + + System.out.print(String.format("%s:\n" + + "\tmode: %s\n" + + "\tcreator: %s,\n" + + "\tcreation timestamp: %s,\n" + + "\tcurrent balance: %s QORT,\n" + + "\tis finished: %b,\n" + + "\tredeem payout: %s QORT,\n" + + "\texpected ARRR: %s ARRR,\n" + + "\tcurrent block height: %d,\n", + tradeData.qortalAtAddress, + tradeData.mode, + tradeData.qortalCreator, + epochMilliFormatter.apply(tradeData.creationTimestamp), + Amounts.prettyAmount(tradeData.qortBalance), + atData.getIsFinished(), + Amounts.prettyAmount(tradeData.qortAmount), + Amounts.prettyAmount(tradeData.expectedForeignAmount), + currentBlockHeight)); + + if (tradeData.mode != AcctMode.OFFERING && tradeData.mode != AcctMode.CANCELLED) { + System.out.println(String.format("\trefund timeout: %d minutes,\n" + + "\trefund height: block %d,\n" + + "\tHASH160 of secret-A: %s,\n" + + "\tPirate Chain P2SH-A nLockTime: %d (%s),\n" + + "\ttrade partner: %s\n" + + "\tpartner's receiving address: %s", + tradeData.refundTimeout, + tradeData.tradeRefundHeight, + HashCode.fromBytes(tradeData.hashOfSecretA).toString().substring(0, 40), + tradeData.lockTimeA, epochMilliFormatter.apply(tradeData.lockTimeA * 1000L), + tradeData.qortalPartnerAddress, + tradeData.qortalPartnerReceivingAddress)); + } + } + + private PrivateKeyAccount createTradeAccount(Repository repository) { + // We actually use a known test account with funds to avoid PoW compute + return Common.getTestAccount(repository, "alice"); + } + +} diff --git a/src/test/java/org/qortal/test/minting/RewardTests.java b/src/test/java/org/qortal/test/minting/RewardTests.java index f7970ace..4aee2de1 100644 --- a/src/test/java/org/qortal/test/minting/RewardTests.java +++ b/src/test/java/org/qortal/test/minting/RewardTests.java @@ -3,10 +3,9 @@ package org.qortal.test.minting; import static org.junit.Assert.*; import java.math.BigInteger; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.util.*; +import org.apache.commons.lang3.reflect.FieldUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.junit.After; @@ -702,6 +701,15 @@ public class RewardTests extends Common { AccountUtils.assertBalance(repository, "chloe", Asset.QORT, chloeInitialBalance+expectedLevel7And8Reward); AccountUtils.assertBalance(repository, "dilbert", Asset.QORT, dilbertInitialBalance+expectedLevel7And8Reward); + // Orphan and ensure balances return to their previous values + BlockUtils.orphanBlocks(repository, 1); + + // Validate the balances + AccountUtils.assertBalance(repository, "alice", Asset.QORT, aliceInitialBalance); + AccountUtils.assertBalance(repository, "bob", Asset.QORT, bobInitialBalance); + AccountUtils.assertBalance(repository, "chloe", Asset.QORT, chloeInitialBalance); + AccountUtils.assertBalance(repository, "dilbert", Asset.QORT, dilbertInitialBalance); + } } @@ -787,6 +795,348 @@ public class RewardTests extends Common { AccountUtils.assertBalance(repository, "chloe", Asset.QORT, chloeInitialBalance+expectedLevel9And10Reward); AccountUtils.assertBalance(repository, "dilbert", Asset.QORT, dilbertInitialBalance+expectedLevel9And10Reward); + // Orphan and ensure balances return to their previous values + BlockUtils.orphanBlocks(repository, 1); + + // Validate the balances + AccountUtils.assertBalance(repository, "alice", Asset.QORT, aliceInitialBalance); + AccountUtils.assertBalance(repository, "bob", Asset.QORT, bobInitialBalance); + AccountUtils.assertBalance(repository, "chloe", Asset.QORT, chloeInitialBalance); + AccountUtils.assertBalance(repository, "dilbert", Asset.QORT, dilbertInitialBalance); + + } + } + + /** Test rewards for level 7 and 8 accounts, when the tier doesn't yet have enough minters in it */ + @Test + public void testLevel7And8RewardsPreActivation() throws DataException, IllegalAccessException { + Common.useSettings("test-settings-v2-reward-levels.json"); + + // Set minAccountsToActivateShareBin to 3 so that share bins 7-8 and 9-10 are considered inactive + FieldUtils.writeField(BlockChain.getInstance(), "minAccountsToActivateShareBin", 3, true); + + try (final Repository repository = RepositoryManager.getRepository()) { + + List cumulativeBlocksByLevel = BlockChain.getInstance().getCumulativeBlocksByLevel(); + List mintingAndOnlineAccounts = new ArrayList<>(); + + // Alice self share online + PrivateKeyAccount aliceSelfShare = Common.getTestAccount(repository, "alice-reward-share"); + mintingAndOnlineAccounts.add(aliceSelfShare); + + // Bob self-share NOT online + + // Chloe self share online + byte[] chloeRewardSharePrivateKey = AccountUtils.rewardShare(repository, "chloe", "chloe", 0); + PrivateKeyAccount chloeRewardShareAccount = new PrivateKeyAccount(repository, chloeRewardSharePrivateKey); + mintingAndOnlineAccounts.add(chloeRewardShareAccount); + + // Dilbert self share online + byte[] dilbertRewardSharePrivateKey = AccountUtils.rewardShare(repository, "dilbert", "dilbert", 0); + PrivateKeyAccount dilbertRewardShareAccount = new PrivateKeyAccount(repository, dilbertRewardSharePrivateKey); + mintingAndOnlineAccounts.add(dilbertRewardShareAccount); + + // Mint enough blocks to bump testAccount levels to 7 and 8 + final int minterBlocksNeeded = cumulativeBlocksByLevel.get(8) - 20; // 20 blocks before level 8, so that the test accounts reach the correct levels + for (int bc = 0; bc < minterBlocksNeeded; ++bc) + BlockMinter.mintTestingBlock(repository, mintingAndOnlineAccounts.toArray(new PrivateKeyAccount[0])); + + // Ensure that the levels are as we expect + assertEquals(7, (int) Common.getTestAccount(repository, "alice").getLevel()); + assertEquals(1, (int) Common.getTestAccount(repository, "bob").getLevel()); + assertEquals(7, (int) Common.getTestAccount(repository, "chloe").getLevel()); + assertEquals(8, (int) Common.getTestAccount(repository, "dilbert").getLevel()); + + // Now that everyone is at level 7 or 8 (except Bob who has only just started minting, so is at level 1), we can capture initial balances + Map> initialBalances = AccountUtils.getBalances(repository, Asset.QORT, Asset.LEGACY_QORA, Asset.QORT_FROM_QORA); + final long aliceInitialBalance = initialBalances.get("alice").get(Asset.QORT); + final long bobInitialBalance = initialBalances.get("bob").get(Asset.QORT); + final long chloeInitialBalance = initialBalances.get("chloe").get(Asset.QORT); + final long dilbertInitialBalance = initialBalances.get("dilbert").get(Asset.QORT); + + // Mint a block + final long blockReward = BlockUtils.getNextBlockReward(repository); + BlockMinter.mintTestingBlock(repository, mintingAndOnlineAccounts.toArray(new PrivateKeyAccount[0])); + + // Ensure we are using the correct block reward value + assertEquals(100000000L, blockReward); + + /* + * Alice, Chloe, and Dilbert are 'online'. + * Chloe is level 7; Dilbert is level 8. + * One founder online (Alice, who is also level 7). + * No legacy QORA holders. + * + * Level 7 and 8 is not yet activated, so its rewards are added to the level 5 and 6 share bin. + * There are no level 5 and 6 online. + * Chloe and Dilbert should receive equal shares of the 35% block reward for levels 5 to 8. + * Alice should receive the remainder (65%). + */ + + final int level5To8SharePercent = 35_00; // 35% (combined 15% and 20%) + final long level5To8ShareAmount = (blockReward * level5To8SharePercent) / 100L / 100L; + final long expectedLevel5To8Reward = level5To8ShareAmount / 2; // The reward is split between Chloe and Dilbert + final long expectedFounderReward = blockReward - level5To8ShareAmount; // Alice should receive the remainder + + // Validate the balances + AccountUtils.assertBalance(repository, "alice", Asset.QORT, aliceInitialBalance+expectedFounderReward); + AccountUtils.assertBalance(repository, "bob", Asset.QORT, bobInitialBalance); // Bob not online so his balance remains the same + AccountUtils.assertBalance(repository, "chloe", Asset.QORT, chloeInitialBalance+expectedLevel5To8Reward); + AccountUtils.assertBalance(repository, "dilbert", Asset.QORT, dilbertInitialBalance+expectedLevel5To8Reward); + + // Orphan and ensure balances return to their previous values + BlockUtils.orphanBlocks(repository, 1); + + // Validate the balances + AccountUtils.assertBalance(repository, "alice", Asset.QORT, aliceInitialBalance); + AccountUtils.assertBalance(repository, "bob", Asset.QORT, bobInitialBalance); + AccountUtils.assertBalance(repository, "chloe", Asset.QORT, chloeInitialBalance); + AccountUtils.assertBalance(repository, "dilbert", Asset.QORT, dilbertInitialBalance); + + } + } + + /** Test rewards for level 9 and 10 accounts, when the tier doesn't yet have enough minters in it. + * Tier 7-8 isn't activated either, so the rewards and minters are all moved to tier 5-6. */ + @Test + public void testLevel9And10RewardsPreActivation() throws DataException, IllegalAccessException { + Common.useSettings("test-settings-v2-reward-levels.json"); + + // Set minAccountsToActivateShareBin to 3 so that share bins 7-8 and 9-10 are considered inactive + FieldUtils.writeField(BlockChain.getInstance(), "minAccountsToActivateShareBin", 3, true); + + try (final Repository repository = RepositoryManager.getRepository()) { + + List cumulativeBlocksByLevel = BlockChain.getInstance().getCumulativeBlocksByLevel(); + List mintingAndOnlineAccounts = new ArrayList<>(); + + // Alice self share online + PrivateKeyAccount aliceSelfShare = Common.getTestAccount(repository, "alice-reward-share"); + mintingAndOnlineAccounts.add(aliceSelfShare); + + // Bob self-share not initially online + + // Chloe self share online + byte[] chloeRewardSharePrivateKey = AccountUtils.rewardShare(repository, "chloe", "chloe", 0); + PrivateKeyAccount chloeRewardShareAccount = new PrivateKeyAccount(repository, chloeRewardSharePrivateKey); + mintingAndOnlineAccounts.add(chloeRewardShareAccount); + + // Dilbert self share online + byte[] dilbertRewardSharePrivateKey = AccountUtils.rewardShare(repository, "dilbert", "dilbert", 0); + PrivateKeyAccount dilbertRewardShareAccount = new PrivateKeyAccount(repository, dilbertRewardSharePrivateKey); + mintingAndOnlineAccounts.add(dilbertRewardShareAccount); + + // Mint enough blocks to bump testAccount levels to 9 and 10 + final int minterBlocksNeeded = cumulativeBlocksByLevel.get(10) - 20; // 20 blocks before level 10, so that the test accounts reach the correct levels + for (int bc = 0; bc < minterBlocksNeeded; ++bc) + BlockMinter.mintTestingBlock(repository, mintingAndOnlineAccounts.toArray(new PrivateKeyAccount[0])); + + // Bob self-share now comes online + byte[] bobRewardSharePrivateKey = AccountUtils.rewardShare(repository, "bob", "bob", 0); + PrivateKeyAccount bobRewardShareAccount = new PrivateKeyAccount(repository, bobRewardSharePrivateKey); + mintingAndOnlineAccounts.add(bobRewardShareAccount); + + // Ensure that the levels are as we expect + assertEquals(9, (int) Common.getTestAccount(repository, "alice").getLevel()); + assertEquals(1, (int) Common.getTestAccount(repository, "bob").getLevel()); + assertEquals(9, (int) Common.getTestAccount(repository, "chloe").getLevel()); + assertEquals(10, (int) Common.getTestAccount(repository, "dilbert").getLevel()); + + // Now that everyone is at level 7 or 8 (except Bob who has only just started minting, so is at level 1), we can capture initial balances + Map> initialBalances = AccountUtils.getBalances(repository, Asset.QORT, Asset.LEGACY_QORA, Asset.QORT_FROM_QORA); + final long aliceInitialBalance = initialBalances.get("alice").get(Asset.QORT); + final long bobInitialBalance = initialBalances.get("bob").get(Asset.QORT); + final long chloeInitialBalance = initialBalances.get("chloe").get(Asset.QORT); + final long dilbertInitialBalance = initialBalances.get("dilbert").get(Asset.QORT); + + // Mint a block + final long blockReward = BlockUtils.getNextBlockReward(repository); + BlockMinter.mintTestingBlock(repository, mintingAndOnlineAccounts.toArray(new PrivateKeyAccount[0])); + + // Ensure we are using the correct block reward value + assertEquals(100000000L, blockReward); + + /* + * Alice, Bob, Chloe, and Dilbert are 'online'. + * Bob is level 1; Chloe is level 9; Dilbert is level 10. + * One founder online (Alice, who is also level 9). + * No legacy QORA holders. + * + * Levels 7+8, and 9+10 are not yet activated, so their rewards are added to the level 5 and 6 share bin. + * There are no levels 5-8 online. + * Chloe and Dilbert should receive equal shares of the 60% block reward for levels 5 to 10. + * Alice should receive the remainder (40%). + */ + + final int level1And2SharePercent = 5_00; // 5% + final int level5To10SharePercent = 60_00; // 60% (combined 15%, 20%, and 25%) + final long level1And2ShareAmount = (blockReward * level1And2SharePercent) / 100L / 100L; + final long level5To10ShareAmount = (blockReward * level5To10SharePercent) / 100L / 100L; + final long expectedLevel1And2Reward = level1And2ShareAmount; // The reward is given entirely to Bob + final long expectedLevel5To10Reward = level5To10ShareAmount / 2; // The reward is split between Chloe and Dilbert + final long expectedFounderReward = blockReward - level1And2ShareAmount - level5To10ShareAmount; // Alice should receive the remainder + + // Validate the balances + AccountUtils.assertBalance(repository, "alice", Asset.QORT, aliceInitialBalance+expectedFounderReward); + AccountUtils.assertBalance(repository, "bob", Asset.QORT, bobInitialBalance+expectedLevel1And2Reward); + AccountUtils.assertBalance(repository, "chloe", Asset.QORT, chloeInitialBalance+expectedLevel5To10Reward); + AccountUtils.assertBalance(repository, "dilbert", Asset.QORT, dilbertInitialBalance+expectedLevel5To10Reward); + + // Orphan and ensure balances return to their previous values + BlockUtils.orphanBlocks(repository, 1); + + // Validate the balances + AccountUtils.assertBalance(repository, "alice", Asset.QORT, aliceInitialBalance); + AccountUtils.assertBalance(repository, "bob", Asset.QORT, bobInitialBalance); + AccountUtils.assertBalance(repository, "chloe", Asset.QORT, chloeInitialBalance); + AccountUtils.assertBalance(repository, "dilbert", Asset.QORT, dilbertInitialBalance); + + } + } + + /** Test rewards for level 7 and 8 accounts, when the tier reaches the minimum number of accounts */ + @Test + public void testLevel7And8RewardsPreAndPostActivation() throws DataException, IllegalAccessException { + Common.useSettings("test-settings-v2-reward-levels.json"); + + // Set minAccountsToActivateShareBin to 2 so that share bins 7-8 and 9-10 are considered inactive at first + FieldUtils.writeField(BlockChain.getInstance(), "minAccountsToActivateShareBin", 2, true); + + try (final Repository repository = RepositoryManager.getRepository()) { + + List cumulativeBlocksByLevel = BlockChain.getInstance().getCumulativeBlocksByLevel(); + List mintingAndOnlineAccounts = new ArrayList<>(); + + // Alice self share online + PrivateKeyAccount aliceSelfShare = Common.getTestAccount(repository, "alice-reward-share"); + mintingAndOnlineAccounts.add(aliceSelfShare); + + // Bob self-share NOT online + + // Chloe self share online + byte[] chloeRewardSharePrivateKey = AccountUtils.rewardShare(repository, "chloe", "chloe", 0); + PrivateKeyAccount chloeRewardShareAccount = new PrivateKeyAccount(repository, chloeRewardSharePrivateKey); + mintingAndOnlineAccounts.add(chloeRewardShareAccount); + + // Dilbert self share online + byte[] dilbertRewardSharePrivateKey = AccountUtils.rewardShare(repository, "dilbert", "dilbert", 0); + PrivateKeyAccount dilbertRewardShareAccount = new PrivateKeyAccount(repository, dilbertRewardSharePrivateKey); + mintingAndOnlineAccounts.add(dilbertRewardShareAccount); + + // Mint enough blocks to bump two of the testAccount levels to 7 + final int minterBlocksNeeded = cumulativeBlocksByLevel.get(7) - 12; // 12 blocks before level 7, so that dilbert and alice have reached level 7, but chloe will reach it in the next 2 blocks + for (int bc = 0; bc < minterBlocksNeeded; ++bc) + BlockMinter.mintTestingBlock(repository, mintingAndOnlineAccounts.toArray(new PrivateKeyAccount[0])); + + // Ensure that the levels are as we expect + assertEquals(7, (int) Common.getTestAccount(repository, "alice").getLevel()); + assertEquals(1, (int) Common.getTestAccount(repository, "bob").getLevel()); + assertEquals(6, (int) Common.getTestAccount(repository, "chloe").getLevel()); + assertEquals(7, (int) Common.getTestAccount(repository, "dilbert").getLevel()); + + // Now that dilbert has reached level 7, we can capture initial balances + Map> initialBalances = AccountUtils.getBalances(repository, Asset.QORT, Asset.LEGACY_QORA, Asset.QORT_FROM_QORA); + final long aliceInitialBalance = initialBalances.get("alice").get(Asset.QORT); + final long bobInitialBalance = initialBalances.get("bob").get(Asset.QORT); + final long chloeInitialBalance = initialBalances.get("chloe").get(Asset.QORT); + final long dilbertInitialBalance = initialBalances.get("dilbert").get(Asset.QORT); + + // Mint a block + long blockReward = BlockUtils.getNextBlockReward(repository); + BlockMinter.mintTestingBlock(repository, mintingAndOnlineAccounts.toArray(new PrivateKeyAccount[0])); + + // Ensure we are using the correct block reward value + assertEquals(100000000L, blockReward); + + /* + * Alice, Chloe, and Dilbert are 'online'. + * Chloe is level 6; Dilbert is level 7. + * One founder online (Alice, who is also level 7). + * No legacy QORA holders. + * + * Level 7 and 8 is not yet activated, so its rewards are added to the level 5 and 6 share bin. + * There are no level 5 and 6 online. + * Chloe and Dilbert should receive equal shares of the 35% block reward for levels 5 to 8. + * Alice should receive the remainder (65%). + */ + + final int level5To8SharePercent = 35_00; // 35% (combined 15% and 20%) + final long level5To8ShareAmount = (blockReward * level5To8SharePercent) / 100L / 100L; + final long expectedLevel5To8Reward = level5To8ShareAmount / 2; // The reward is split between Chloe and Dilbert + final long expectedFounderReward = blockReward - level5To8ShareAmount; // Alice should receive the remainder + + // Validate the balances + AccountUtils.assertBalance(repository, "alice", Asset.QORT, aliceInitialBalance+expectedFounderReward); + AccountUtils.assertBalance(repository, "bob", Asset.QORT, bobInitialBalance); // Bob not online so his balance remains the same + AccountUtils.assertBalance(repository, "chloe", Asset.QORT, chloeInitialBalance+expectedLevel5To8Reward); + AccountUtils.assertBalance(repository, "dilbert", Asset.QORT, dilbertInitialBalance+expectedLevel5To8Reward); + + // Ensure that the levels are as we expect + assertEquals(7, (int) Common.getTestAccount(repository, "alice").getLevel()); + assertEquals(1, (int) Common.getTestAccount(repository, "bob").getLevel()); + assertEquals(6, (int) Common.getTestAccount(repository, "chloe").getLevel()); + assertEquals(7, (int) Common.getTestAccount(repository, "dilbert").getLevel()); + + // Capture pre-activation balances + Map> preActivationBalances = AccountUtils.getBalances(repository, Asset.QORT, Asset.LEGACY_QORA, Asset.QORT_FROM_QORA); + final long alicePreActivationBalance = preActivationBalances.get("alice").get(Asset.QORT); + final long bobPreActivationBalance = preActivationBalances.get("bob").get(Asset.QORT); + final long chloePreActivationBalance = preActivationBalances.get("chloe").get(Asset.QORT); + final long dilbertPreActivationBalance = preActivationBalances.get("dilbert").get(Asset.QORT); + + // Mint another block + blockReward = BlockUtils.getNextBlockReward(repository); + BlockMinter.mintTestingBlock(repository, mintingAndOnlineAccounts.toArray(new PrivateKeyAccount[0])); + + // Ensure that the levels are as we expect (chloe has now increased to level 7; level 7-8 is now activated) + assertEquals(7, (int) Common.getTestAccount(repository, "alice").getLevel()); + assertEquals(1, (int) Common.getTestAccount(repository, "bob").getLevel()); + assertEquals(7, (int) Common.getTestAccount(repository, "chloe").getLevel()); + assertEquals(7, (int) Common.getTestAccount(repository, "dilbert").getLevel()); + + /* + * Alice, Chloe, and Dilbert are 'online'. + * Chloe and Dilbert are level 7. + * One founder online (Alice, who is also level 7). + * No legacy QORA holders. + * + * Level 7 and 8 is now activated, so its rewards are paid out in the normal way. + * There are no level 5 and 6 online. + * Chloe and Dilbert should receive equal shares of the 20% block reward for levels 7 to 8. + * Alice should receive the remainder (80%). + */ + + final int level7To8SharePercent = 20_00; // 20% + final long level7To8ShareAmount = (blockReward * level7To8SharePercent) / 100L / 100L; + final long expectedLevel7To8Reward = level7To8ShareAmount / 2; // The reward is split between Chloe and Dilbert + final long newExpectedFounderReward = blockReward - level7To8ShareAmount; // Alice should receive the remainder + + // Validate the balances + AccountUtils.assertBalance(repository, "alice", Asset.QORT, alicePreActivationBalance+newExpectedFounderReward); + AccountUtils.assertBalance(repository, "bob", Asset.QORT, bobPreActivationBalance); // Bob not online so his balance remains the same + AccountUtils.assertBalance(repository, "chloe", Asset.QORT, chloePreActivationBalance+expectedLevel7To8Reward); + AccountUtils.assertBalance(repository, "dilbert", Asset.QORT, dilbertPreActivationBalance+expectedLevel7To8Reward); + + + // Orphan and ensure balances return to their pre-activation values + BlockUtils.orphanBlocks(repository, 1); + + // Validate the balances + AccountUtils.assertBalance(repository, "alice", Asset.QORT, alicePreActivationBalance); + AccountUtils.assertBalance(repository, "bob", Asset.QORT, bobPreActivationBalance); + AccountUtils.assertBalance(repository, "chloe", Asset.QORT, chloePreActivationBalance); + AccountUtils.assertBalance(repository, "dilbert", Asset.QORT, dilbertPreActivationBalance); + + + // Orphan again and ensure balances return to their initial values + BlockUtils.orphanBlocks(repository, 1); + + // Validate the balances + AccountUtils.assertBalance(repository, "alice", Asset.QORT, aliceInitialBalance); + AccountUtils.assertBalance(repository, "bob", Asset.QORT, bobInitialBalance); + AccountUtils.assertBalance(repository, "chloe", Asset.QORT, chloeInitialBalance); + AccountUtils.assertBalance(repository, "dilbert", Asset.QORT, dilbertInitialBalance); + } } diff --git a/src/test/resources/test-chain-v2-block-timestamps.json b/src/test/resources/test-chain-v2-block-timestamps.json index 21de096a..bad908eb 100644 --- a/src/test/resources/test-chain-v2-block-timestamps.json +++ b/src/test/resources/test-chain-v2-block-timestamps.json @@ -20,14 +20,16 @@ { "height": 21, "reward": 1 } ], "sharesByLevel": [ - { "levels": [ 1, 2 ], "share": 0.05 }, - { "levels": [ 3, 4 ], "share": 0.10 }, - { "levels": [ 5, 6 ], "share": 0.15 }, - { "levels": [ 7, 8 ], "share": 0.20 }, - { "levels": [ 9, 10 ], "share": 0.25 } + { "id": 1, "levels": [ 1, 2 ], "share": 0.05 }, + { "id": 2, "levels": [ 3, 4 ], "share": 0.10 }, + { "id": 3, "levels": [ 5, 6 ], "share": 0.15 }, + { "id": 4, "levels": [ 7, 8 ], "share": 0.20 }, + { "id": 5, "levels": [ 9, 10 ], "share": 0.25 } ], "qoraHoldersShare": 0.20, "qoraPerQortReward": 250, + "minAccountsToActivateShareBin": 30, + "shareBinActivationMinLevel": 7, "blocksNeededByLevel": [ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 ], "blockTimingsByHeight": [ { "height": 1, "target": 60000, "deviation": 30000, "power": 0.2 }, diff --git a/src/test/resources/test-chain-v2-disable-reference.json b/src/test/resources/test-chain-v2-disable-reference.json index f47a96b3..e7be1ac7 100644 --- a/src/test/resources/test-chain-v2-disable-reference.json +++ b/src/test/resources/test-chain-v2-disable-reference.json @@ -24,14 +24,16 @@ { "height": 21, "reward": 1 } ], "sharesByLevel": [ - { "levels": [ 1, 2 ], "share": 0.05 }, - { "levels": [ 3, 4 ], "share": 0.10 }, - { "levels": [ 5, 6 ], "share": 0.15 }, - { "levels": [ 7, 8 ], "share": 0.20 }, - { "levels": [ 9, 10 ], "share": 0.25 } + { "id": 1, "levels": [ 1, 2 ], "share": 0.05 }, + { "id": 2, "levels": [ 3, 4 ], "share": 0.10 }, + { "id": 3, "levels": [ 5, 6 ], "share": 0.15 }, + { "id": 4, "levels": [ 7, 8 ], "share": 0.20 }, + { "id": 5, "levels": [ 9, 10 ], "share": 0.25 } ], "qoraHoldersShare": 0.20, "qoraPerQortReward": 250, + "minAccountsToActivateShareBin": 30, + "shareBinActivationMinLevel": 7, "blocksNeededByLevel": [ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 ], "blockTimingsByHeight": [ { "height": 1, "target": 60000, "deviation": 30000, "power": 0.2 } diff --git a/src/test/resources/test-chain-v2-founder-rewards.json b/src/test/resources/test-chain-v2-founder-rewards.json index 61b6443c..37c79ce5 100644 --- a/src/test/resources/test-chain-v2-founder-rewards.json +++ b/src/test/resources/test-chain-v2-founder-rewards.json @@ -25,14 +25,16 @@ { "height": 21, "reward": 1 } ], "sharesByLevel": [ - { "levels": [ 1, 2 ], "share": 0.05 }, - { "levels": [ 3, 4 ], "share": 0.10 }, - { "levels": [ 5, 6 ], "share": 0.15 }, - { "levels": [ 7, 8 ], "share": 0.20 }, - { "levels": [ 9, 10 ], "share": 0.25 } + { "id": 1, "levels": [ 1, 2 ], "share": 0.05 }, + { "id": 2, "levels": [ 3, 4 ], "share": 0.10 }, + { "id": 3, "levels": [ 5, 6 ], "share": 0.15 }, + { "id": 4, "levels": [ 7, 8 ], "share": 0.20 }, + { "id": 5, "levels": [ 9, 10 ], "share": 0.25 } ], "qoraHoldersShare": 0.20, "qoraPerQortReward": 250, + "minAccountsToActivateShareBin": 30, + "shareBinActivationMinLevel": 7, "blocksNeededByLevel": [ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 ], "blockTimingsByHeight": [ { "height": 1, "target": 60000, "deviation": 30000, "power": 0.2 } diff --git a/src/test/resources/test-chain-v2-leftover-reward.json b/src/test/resources/test-chain-v2-leftover-reward.json index 0f8c95d0..fbb7c553 100644 --- a/src/test/resources/test-chain-v2-leftover-reward.json +++ b/src/test/resources/test-chain-v2-leftover-reward.json @@ -25,14 +25,16 @@ { "height": 21, "reward": 1 } ], "sharesByLevel": [ - { "levels": [ 1, 2 ], "share": 0.05 }, - { "levels": [ 3, 4 ], "share": 0.10 }, - { "levels": [ 5, 6 ], "share": 0.15 }, - { "levels": [ 7, 8 ], "share": 0.20 }, - { "levels": [ 9, 10 ], "share": 0.25 } + { "id": 1, "levels": [ 1, 2 ], "share": 0.05 }, + { "id": 2, "levels": [ 3, 4 ], "share": 0.10 }, + { "id": 3, "levels": [ 5, 6 ], "share": 0.15 }, + { "id": 4, "levels": [ 7, 8 ], "share": 0.20 }, + { "id": 5, "levels": [ 9, 10 ], "share": 0.25 } ], "qoraHoldersShare": 0.20, "qoraPerQortReward": 250, + "minAccountsToActivateShareBin": 30, + "shareBinActivationMinLevel": 7, "blocksNeededByLevel": [ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 ], "blockTimingsByHeight": [ { "height": 1, "target": 60000, "deviation": 30000, "power": 0.2 } diff --git a/src/test/resources/test-chain-v2-minting.json b/src/test/resources/test-chain-v2-minting.json index eca11cb3..085152d2 100644 --- a/src/test/resources/test-chain-v2-minting.json +++ b/src/test/resources/test-chain-v2-minting.json @@ -25,14 +25,16 @@ { "height": 21, "reward": 1 } ], "sharesByLevel": [ - { "levels": [ 1, 2 ], "share": 0.05 }, - { "levels": [ 3, 4 ], "share": 0.10 }, - { "levels": [ 5, 6 ], "share": 0.15 }, - { "levels": [ 7, 8 ], "share": 0.20 }, - { "levels": [ 9, 10 ], "share": 0.25 } + { "id": 1, "levels": [ 1, 2 ], "share": 0.05 }, + { "id": 2, "levels": [ 3, 4 ], "share": 0.10 }, + { "id": 3, "levels": [ 5, 6 ], "share": 0.15 }, + { "id": 4, "levels": [ 7, 8 ], "share": 0.20 }, + { "id": 5, "levels": [ 9, 10 ], "share": 0.25 } ], "qoraHoldersShare": 0.20, "qoraPerQortReward": 250, + "minAccountsToActivateShareBin": 30, + "shareBinActivationMinLevel": 7, "blocksNeededByLevel": [ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 ], "blockTimingsByHeight": [ { "height": 1, "target": 60000, "deviation": 30000, "power": 0.2 } diff --git a/src/test/resources/test-chain-v2-qora-holder-extremes.json b/src/test/resources/test-chain-v2-qora-holder-extremes.json index 9839e215..b8ec21a4 100644 --- a/src/test/resources/test-chain-v2-qora-holder-extremes.json +++ b/src/test/resources/test-chain-v2-qora-holder-extremes.json @@ -25,14 +25,16 @@ { "height": 21, "reward": 1 } ], "sharesByLevel": [ - { "levels": [ 1, 2 ], "share": 0.05 }, - { "levels": [ 3, 4 ], "share": 0.10 }, - { "levels": [ 5, 6 ], "share": 0.15 }, - { "levels": [ 7, 8 ], "share": 0.20 }, - { "levels": [ 9, 10 ], "share": 0.25 } + { "id": 1, "levels": [ 1, 2 ], "share": 0.05 }, + { "id": 2, "levels": [ 3, 4 ], "share": 0.10 }, + { "id": 3, "levels": [ 5, 6 ], "share": 0.15 }, + { "id": 4, "levels": [ 7, 8 ], "share": 0.20 }, + { "id": 5, "levels": [ 9, 10 ], "share": 0.25 } ], "qoraHoldersShare": 0.20, "qoraPerQortReward": 250, + "minAccountsToActivateShareBin": 30, + "shareBinActivationMinLevel": 7, "blocksNeededByLevel": [ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 ], "blockTimingsByHeight": [ { "height": 1, "target": 60000, "deviation": 30000, "power": 0.2 } diff --git a/src/test/resources/test-chain-v2-qora-holder.json b/src/test/resources/test-chain-v2-qora-holder.json index c02243b2..8a1acd0d 100644 --- a/src/test/resources/test-chain-v2-qora-holder.json +++ b/src/test/resources/test-chain-v2-qora-holder.json @@ -25,14 +25,16 @@ { "height": 21, "reward": 1 } ], "sharesByLevel": [ - { "levels": [ 1, 2 ], "share": 0.05 }, - { "levels": [ 3, 4 ], "share": 0.10 }, - { "levels": [ 5, 6 ], "share": 0.15 }, - { "levels": [ 7, 8 ], "share": 0.20 }, - { "levels": [ 9, 10 ], "share": 0.25 } + { "id": 1, "levels": [ 1, 2 ], "share": 0.05 }, + { "id": 2, "levels": [ 3, 4 ], "share": 0.10 }, + { "id": 3, "levels": [ 5, 6 ], "share": 0.15 }, + { "id": 4, "levels": [ 7, 8 ], "share": 0.20 }, + { "id": 5, "levels": [ 9, 10 ], "share": 0.25 } ], "qoraHoldersShare": 0.20, "qoraPerQortReward": 250, + "minAccountsToActivateShareBin": 30, + "shareBinActivationMinLevel": 7, "blocksNeededByLevel": [ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 ], "blockTimingsByHeight": [ { "height": 1, "target": 60000, "deviation": 30000, "power": 0.2 } diff --git a/src/test/resources/test-chain-v2-reward-levels.json b/src/test/resources/test-chain-v2-reward-levels.json index 70470ffa..8461a593 100644 --- a/src/test/resources/test-chain-v2-reward-levels.json +++ b/src/test/resources/test-chain-v2-reward-levels.json @@ -25,14 +25,16 @@ { "height": 21, "reward": 1 } ], "sharesByLevel": [ - { "levels": [ 1, 2 ], "share": 0.05 }, - { "levels": [ 3, 4 ], "share": 0.10 }, - { "levels": [ 5, 6 ], "share": 0.15 }, - { "levels": [ 7, 8 ], "share": 0.20 }, - { "levels": [ 9, 10 ], "share": 0.25 } + { "id": 1, "levels": [ 1, 2 ], "share": 0.05 }, + { "id": 2, "levels": [ 3, 4 ], "share": 0.10 }, + { "id": 3, "levels": [ 5, 6 ], "share": 0.15 }, + { "id": 4, "levels": [ 7, 8 ], "share": 0.20 }, + { "id": 5, "levels": [ 9, 10 ], "share": 0.25 } ], "qoraHoldersShare": 0.20, "qoraPerQortReward": 250, + "minAccountsToActivateShareBin": 1, + "shareBinActivationMinLevel": 7, "blocksNeededByLevel": [ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 ], "blockTimingsByHeight": [ { "height": 1, "target": 60000, "deviation": 30000, "power": 0.2 } diff --git a/src/test/resources/test-chain-v2-reward-scaling.json b/src/test/resources/test-chain-v2-reward-scaling.json index 4140b3d2..4d432224 100644 --- a/src/test/resources/test-chain-v2-reward-scaling.json +++ b/src/test/resources/test-chain-v2-reward-scaling.json @@ -25,14 +25,16 @@ { "height": 21, "reward": 1 } ], "sharesByLevel": [ - { "levels": [ 1, 2 ], "share": 0.05 }, - { "levels": [ 3, 4 ], "share": 0.10 }, - { "levels": [ 5, 6 ], "share": 0.15 }, - { "levels": [ 7, 8 ], "share": 0.20 }, - { "levels": [ 9, 10 ], "share": 0.25 } + { "id": 1, "levels": [ 1, 2 ], "share": 0.05 }, + { "id": 2, "levels": [ 3, 4 ], "share": 0.10 }, + { "id": 3, "levels": [ 5, 6 ], "share": 0.15 }, + { "id": 4, "levels": [ 7, 8 ], "share": 0.20 }, + { "id": 5, "levels": [ 9, 10 ], "share": 0.25 } ], "qoraHoldersShare": 0.20, "qoraPerQortReward": 250, + "minAccountsToActivateShareBin": 30, + "shareBinActivationMinLevel": 7, "blocksNeededByLevel": [ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 ], "blockTimingsByHeight": [ { "height": 1, "target": 60000, "deviation": 30000, "power": 0.2 } diff --git a/src/test/resources/test-chain-v2-reward-shares.json b/src/test/resources/test-chain-v2-reward-shares.json index 2b024825..9dd3c223 100644 --- a/src/test/resources/test-chain-v2-reward-shares.json +++ b/src/test/resources/test-chain-v2-reward-shares.json @@ -24,14 +24,16 @@ { "height": 21, "reward": 1 } ], "sharesByLevel": [ - { "levels": [ 1, 2 ], "share": 0.05 }, - { "levels": [ 3, 4 ], "share": 0.10 }, - { "levels": [ 5, 6 ], "share": 0.15 }, - { "levels": [ 7, 8 ], "share": 0.20 }, - { "levels": [ 9, 10 ], "share": 0.25 } + { "id": 1, "levels": [ 1, 2 ], "share": 0.05 }, + { "id": 2, "levels": [ 3, 4 ], "share": 0.10 }, + { "id": 3, "levels": [ 5, 6 ], "share": 0.15 }, + { "id": 4, "levels": [ 7, 8 ], "share": 0.20 }, + { "id": 5, "levels": [ 9, 10 ], "share": 0.25 } ], "qoraHoldersShare": 0.20, "qoraPerQortReward": 250, + "minAccountsToActivateShareBin": 30, + "shareBinActivationMinLevel": 7, "blocksNeededByLevel": [ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 ], "blockTimingsByHeight": [ { "height": 1, "target": 60000, "deviation": 30000, "power": 0.2 } diff --git a/src/test/resources/test-chain-v2.json b/src/test/resources/test-chain-v2.json index 07e308e6..f6376be4 100644 --- a/src/test/resources/test-chain-v2.json +++ b/src/test/resources/test-chain-v2.json @@ -25,14 +25,16 @@ { "height": 21, "reward": 1 } ], "sharesByLevel": [ - { "levels": [ 1, 2 ], "share": 0.05 }, - { "levels": [ 3, 4 ], "share": 0.10 }, - { "levels": [ 5, 6 ], "share": 0.15 }, - { "levels": [ 7, 8 ], "share": 0.20 }, - { "levels": [ 9, 10 ], "share": 0.25 } + { "id": 1, "levels": [ 1, 2 ], "share": 0.05 }, + { "id": 2, "levels": [ 3, 4 ], "share": 0.10 }, + { "id": 3, "levels": [ 5, 6 ], "share": 0.15 }, + { "id": 4, "levels": [ 7, 8 ], "share": 0.20 }, + { "id": 5, "levels": [ 9, 10 ], "share": 0.25 } ], "qoraHoldersShare": 0.20, "qoraPerQortReward": 250, + "minAccountsToActivateShareBin": 30, + "shareBinActivationMinLevel": 7, "blocksNeededByLevel": [ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 ], "blockTimingsByHeight": [ { "height": 1, "target": 60000, "deviation": 30000, "power": 0.2 } diff --git a/src/test/resources/test-settings-v2.json b/src/test/resources/test-settings-v2.json index b2ad3db8..0a604efa 100644 --- a/src/test/resources/test-settings-v2.json +++ b/src/test/resources/test-settings-v2.json @@ -15,5 +15,6 @@ "tempDataPath": "data-test/_temp", "listsPath": "lists-test", "storagePolicy": "FOLLOWED_OR_VIEWED", - "maxStorageCapacity": 104857600 + "maxStorageCapacity": 104857600, + "arrrDefaultBirthday": 1900000 } diff --git a/tools/qdata b/tools/qdn similarity index 99% rename from tools/qdata rename to tools/qdn index 5ca61e45..869bf5c4 100755 --- a/tools/qdata +++ b/tools/qdn @@ -2,7 +2,7 @@ # Qortal defaults host="localhost" -port=12393 +port=12391 if [ -z "$*" ]; then echo "Usage:"