web3j/web3j-quorum

Sporadic failures when sending private transactions

sebaraba opened this issue · 1 comments

The v-offset is set to 37 or 38 for private transactions. This helps quorum understand whether we are dealing with a private or non-private transaction. At the moment the v-offset is manipulated as follows:

 private fun setPrivate(message: ByteArray): ByteArray {
       val vOffset = message.size - 67
       when (message[vOffset]) {
           28.toByte() -> message[vOffset] = 38
           else -> message[vOffset] = 37
       }
       return message
   }

To identify the v-offset we made a naive assumption that signature data will always have the same length. Thus we would find the v-offset just before the 67th byte starting at the end of the payload. However, after more testings, we learned that the length of the signed that might vary.
A proposed solution to overcome this problem would adapting the setPrivate() method to something similar to this:

   private fun setPrivate(message: ByteArray): ByteArray {
       val rlpList = RlpDecoder.decode(message).values[0]
       if ( rlpList is RlpList) {
           val rlpListSize = rlpList.values.size
           val vField = rlpList.values[rlpListSize - 3]
           if (vField is RlpString) {
               when (vField.bytes[0]) {
                   28.toByte() -> vField.bytes[0] = 38
                   else -> vField.bytes[0] = 37
               }
           }
           return RlpEncoder.encode(rlpList)
       }
       return message
   }

Using an RLP decoder we can make sure that what we never miss the position of the v-offset in the signed data.

stale commented

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.