233 lines
6.8 KiB
Plaintext
233 lines
6.8 KiB
Plaintext
!import "arboricx-common.tri" !Local
|
|
|
|
readNodeRecord = (bs :
|
|
bindResult (readBytes 32 bs)
|
|
(nodeHash afterNodeHash :
|
|
bindResult (readBytes 4 afterNodeHash)
|
|
(payloadLength afterPayloadLength :
|
|
bindResult (readBytes (u32BEBytesToNat payloadLength) afterPayloadLength)
|
|
(payload afterPayload :
|
|
ok
|
|
(pair nodeHash
|
|
(pair payloadLength payload))
|
|
afterPayload))))
|
|
|
|
nodeRecordHash = (nodeRecord :
|
|
matchPair
|
|
(nodeHash _ : nodeHash)
|
|
nodeRecord)
|
|
|
|
nodeRecordPayloadLength = (nodeRecord :
|
|
matchPair
|
|
(_ payload :
|
|
matchPair
|
|
(payloadLength _ : payloadLength)
|
|
payload)
|
|
nodeRecord)
|
|
|
|
nodeRecordPayload = (nodeRecord :
|
|
matchPair
|
|
(_ payload :
|
|
matchPair
|
|
(_ nodePayload : nodePayload)
|
|
payload)
|
|
nodeRecord)
|
|
|
|
nodePayloadKind = (nodePayload : bytesHead nodePayload)
|
|
|
|
nodePayloadHasTag? = (tag nodePayload :
|
|
triage
|
|
false
|
|
(actualTag : byteEq? actualTag tag)
|
|
(_ _ : false)
|
|
(nodePayloadKind nodePayload))
|
|
|
|
nodePayloadLeaf? = (nodePayload : bytesEq? [(0)] nodePayload)
|
|
|
|
nodePayloadStem? = (nodePayload :
|
|
and?
|
|
(nodePayloadHasTag? nodePayloadStemTag nodePayload)
|
|
(equal? (bytesLength nodePayload) 33))
|
|
|
|
nodePayloadFork? = (nodePayload :
|
|
and?
|
|
(nodePayloadHasTag? nodePayloadForkTag nodePayload)
|
|
(equal? (bytesLength nodePayload) 65))
|
|
|
|
nodePayloadValid? = (nodePayload :
|
|
or?
|
|
(nodePayloadLeaf? nodePayload)
|
|
(or?
|
|
(nodePayloadStem? nodePayload)
|
|
(nodePayloadFork? nodePayload)))
|
|
|
|
nodePayloadStemChildHash = (nodePayload : bytesTake 32 (bytesDrop 1 nodePayload))
|
|
nodePayloadForkLeftHash = (nodePayload : bytesTake 32 (bytesDrop 1 nodePayload))
|
|
nodePayloadForkRightHash = (nodePayload : bytesTake 32 (bytesDrop 33 nodePayload))
|
|
|
|
nodeRecordPayloadValid? = (nodeRecord : nodePayloadValid? (nodeRecordPayload nodeRecord))
|
|
|
|
nodeRecordsHaveInvalidPayload? = y (self nodeRecords :
|
|
matchList
|
|
false
|
|
(nodeRecord rest :
|
|
or?
|
|
(not? (nodeRecordPayloadValid? nodeRecord))
|
|
(self rest))
|
|
nodeRecords)
|
|
|
|
nodeRecordsHaveHash? = y (self nodeRecords nodeHash :
|
|
matchList
|
|
false
|
|
(nodeRecord rest :
|
|
or?
|
|
(bytesEq? nodeHash (nodeRecordHash nodeRecord))
|
|
(self rest nodeHash))
|
|
nodeRecords)
|
|
|
|
nodeRecordsHaveDuplicateHashes? = y (self nodeRecords :
|
|
matchList
|
|
false
|
|
(nodeRecord rest :
|
|
or?
|
|
(nodeRecordsHaveHash? rest (nodeRecordHash nodeRecord))
|
|
(self rest))
|
|
nodeRecords)
|
|
|
|
lookupNodeRecord_ = y (self nodeRecords nodeHash :
|
|
matchList
|
|
nothing
|
|
(nodeRecord rest :
|
|
matchBool
|
|
(just nodeRecord)
|
|
(self rest nodeHash)
|
|
(bytesEq? nodeHash (nodeRecordHash nodeRecord)))
|
|
nodeRecords)
|
|
|
|
lookupNodeRecord = (nodeHash nodeRecords : lookupNodeRecord_ nodeRecords nodeHash)
|
|
|
|
nodeRecordChildHashes = (nodeRecord :
|
|
(nodePayload :
|
|
matchBool
|
|
t
|
|
(matchBool
|
|
(pair (nodePayloadStemChildHash nodePayload) t)
|
|
(pair (nodePayloadForkLeftHash nodePayload)
|
|
(pair (nodePayloadForkRightHash nodePayload) t))
|
|
(nodePayloadStem? nodePayload))
|
|
(nodePayloadLeaf? nodePayload))
|
|
(nodeRecordPayload nodeRecord))
|
|
|
|
nodeHashPresent? = (nodeHash nodeRecords : nodeRecordsHaveHash? nodeRecords nodeHash)
|
|
|
|
nodeChildHashesPresent? = y (self childHashes nodeRecords :
|
|
matchList
|
|
true
|
|
(childHash rest :
|
|
and?
|
|
(nodeHashPresent? childHash nodeRecords)
|
|
(self rest nodeRecords))
|
|
childHashes)
|
|
|
|
nodeRecordChildrenPresent? = (nodeRecord nodeRecords :
|
|
nodeChildHashesPresent? (nodeRecordChildHashes nodeRecord) nodeRecords)
|
|
|
|
nodeRecordsClosed? = y (self nodeRecords allNodeRecords :
|
|
matchList
|
|
true
|
|
(nodeRecord rest :
|
|
and?
|
|
(nodeRecordChildrenPresent? nodeRecord allNodeRecords)
|
|
(self rest allNodeRecords))
|
|
nodeRecords)
|
|
|
|
validateNodeRecords = (nodeRecords rest :
|
|
matchBool
|
|
(err errInvalidNodePayload rest)
|
|
(matchBool
|
|
(err errDuplicateNode rest)
|
|
(matchBool
|
|
(ok nodeRecords rest)
|
|
(err errMissingNode rest)
|
|
(nodeRecordsClosed? nodeRecords nodeRecords))
|
|
(nodeRecordsHaveDuplicateHashes? nodeRecords))
|
|
(nodeRecordsHaveInvalidPayload? nodeRecords))
|
|
|
|
readNodeRecords_ = y (self bs nodeCount i acc :
|
|
matchBool
|
|
(ok (reverse acc) bs)
|
|
(bindResult (readNodeRecord bs)
|
|
(nodeRecord afterNodeRecord :
|
|
self afterNodeRecord nodeCount (succ i) (pair nodeRecord acc)))
|
|
(equal? i nodeCount))
|
|
|
|
readNodeRecords = (nodeCount bs : readNodeRecords_ bs nodeCount 0 t)
|
|
|
|
readNodesSection = (bs :
|
|
bindResult (readBytes 8 bs)
|
|
(nodeCount afterNodeCount :
|
|
bindResult (readNodeRecords (u64BEBytesToNat nodeCount) afterNodeCount)
|
|
(nodeRecords afterNodeRecords :
|
|
bindResult (validateNodeRecords nodeRecords afterNodeRecords)
|
|
(validNodeRecords afterValidNodeRecords :
|
|
ok (pair nodeCount validNodeRecords) afterValidNodeRecords))))
|
|
|
|
readNodesSectionComplete = (bs :
|
|
bindResult (readNodesSection bs)
|
|
(nodesSection afterNodesSection :
|
|
matchBool
|
|
(ok nodesSection afterNodesSection)
|
|
(err errUnexpectedBytes afterNodesSection)
|
|
(bytesNil? afterNodesSection)))
|
|
|
|
readArboricxNodesSection = (bs :
|
|
bindResult (readArboricxContainer bs)
|
|
(container afterContainer :
|
|
matchPair
|
|
(_ directory :
|
|
bindResult (sectionBytesOrErr arboricxNodesSectionId directory bs afterContainer)
|
|
(nodesBytes _ :
|
|
bindResult (readNodesSectionComplete nodesBytes)
|
|
(nodesSection _ : ok nodesSection afterContainer)))
|
|
container))
|
|
|
|
nodesSectionCount = (nodesSection :
|
|
matchPair
|
|
(nodeCount _ : nodeCount)
|
|
nodesSection)
|
|
|
|
nodesSectionRecords = (nodesSection :
|
|
matchPair
|
|
(_ nodeRecords : nodeRecords)
|
|
nodesSection)
|
|
|
|
nodeRecordToTreeWith = (self nodeRecords nodeRecord :
|
|
(nodePayload :
|
|
matchBool
|
|
(ok t t)
|
|
(matchBool
|
|
(bindResult (self (nodePayloadStemChildHash nodePayload) nodeRecords)
|
|
(child _ : ok (t child) t))
|
|
(bindResult (self (nodePayloadForkLeftHash nodePayload) nodeRecords)
|
|
(left _ :
|
|
bindResult (self (nodePayloadForkRightHash nodePayload) nodeRecords)
|
|
(right _ : ok (pair left right) t)))
|
|
(nodePayloadStem? nodePayload))
|
|
(nodePayloadLeaf? nodePayload))
|
|
(nodeRecordPayload nodeRecord))
|
|
|
|
nodeHashToTree = y (self nodeHash nodeRecords :
|
|
triage
|
|
(err errMissingNode t)
|
|
(nodeRecord : nodeRecordToTreeWith self nodeRecords nodeRecord)
|
|
(_ _ : err errMissingNode t)
|
|
(lookupNodeRecord nodeHash nodeRecords))
|
|
|
|
readArboricxTreeFromHash = (rootHash bs :
|
|
bindResult (readArboricxNodesSection bs)
|
|
(nodesSection afterContainer :
|
|
bindResult (nodeHashToTree rootHash (nodesSectionRecords nodesSection))
|
|
(tree _ : ok tree afterContainer)))
|
|
|
|
readArboricxExecutableFromHash = readArboricxTreeFromHash
|