Created
February 6, 2021 20:50
-
-
Save kayabaNerve/a03fdc506a00069e81c29afc5d6816bb to your computer and use it in GitHub Desktop.
parseSend supporting missing work.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ../../../lib/[Errors, Hash] | |
import ../../../Wallet/Wallet | |
import ../../../Database/Transactions/objects/SendObj | |
import ../SerializeCommon | |
proc parseSend*( | |
sendStr: string, | |
diff: uint32, | |
allowMissingWork: bool = false | |
): Send {.forceCheck: [ | |
ValueError, | |
Spam | |
].} = | |
#Verify the input length. | |
if sendStr.len < BYTE_LEN: | |
raise newLoggedException(ValueError, "parseSend not handed enough data to get the amount of inputs.") | |
let outputLenPos: int = BYTE_LEN + (int(sendStr[0]) * (HASH_LEN + BYTE_LEN)) | |
if sendStr.len < outputLenPos + BYTE_LEN: | |
raise newLoggedException(ValueError, "parseSend not handed enough data to get the amount of outputs.") | |
var | |
#Inputs Length | Inputs | Outputs Length | Signature | |
sendSeq: seq[string] = sendStr.deserialize( | |
BYTE_LEN, | |
sendStr[0].fromBinary() * (HASH_LEN + BYTE_LEN), | |
BYTE_LEN, | |
sendStr[outputLenPos].fromBinary() * (ED_PUBLIC_KEY_LEN + MEROS_LEN), | |
ED_SIGNATURE_LEN | |
) | |
parsedLen: int = sendSeq.join("").len | |
#The way this is written also handles too large of a buffer. | |
hasWork: bool = (sendStr.len - parsedLen) == 0 | |
if (not allowMissingWork) and (not hasWork): | |
raise newException(ValueError, "Send is incomplete.") | |
#Make sure the only difference is the work field. | |
if allowMissingWork and (not hasWork) and ((sendStr.len - parsedLen) != INT_LEN): | |
raise newException("While the work is allowed to be missing, even more is missing or additional data was provided.") | |
#Convert the inputs. | |
var inputs: seq[FundedInput] = newSeq[FundedInput](sendSeq[0].fromBinary()) | |
if inputs.len == 0: | |
raise newLoggedException(ValueError, "parseSend handed a Send with no inputs.") | |
for i in countup(0, sendSeq[1].len - 1, 33): | |
inputs[i div 33] = newFundedInput(sendSeq[1][i ..< i + 32].toHash[:256](), sendSeq[1][i + 32].fromBinary()) | |
#Convert the outputs. | |
var outputs: seq[SendOutput] = newSeq[SendOutput](sendSeq[2].fromBinary()) | |
if outputs.len == 0: | |
raise newLoggedException(ValueError, "parseSend handed a Send with no outputs.") | |
for i in countup(0, sendSeq[3].len - 1, 40): | |
outputs[i div 40] = newSendOutput( | |
newEdPublicKey(sendSeq[3][i ..< i + 32]), | |
uint64(sendSeq[3][i + 32 ..< i + 40].fromBinary()) | |
) | |
#Create the Send. | |
result = newSendObj(inputs, outputs) | |
result.hash = hash | |
result.signature = newEdSignature(sendSeq[4]) | |
#Verify the Send isn't spam, if the Send has work. | |
if hasWork: | |
result.proof = cast[uint32](sendStr[sendStr.len - INT_LEN ..< sendStr.len].fromBinary()) | |
result.argon = Argon( | |
Blake256("\2" & sendStr[0 ..< sendStr.len - (ED_SIGNATURE_LEN + INT_LEN)]).serialize(), | |
result.proof.toBinary(8) | |
) | |
if result.argon.overflows(result.getDifficultyFactor() * diff): | |
raise newSpam("Send didn't beat the difficulty.", hash, argon, factor * diff) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment