MCPcopy Create free account
hub / github.com/ElementsProject/elements / simplicity_fillWitnessData

Function simplicity_fillWitnessData

src/simplicity/dag.c:484–560  ·  view source on GitHub ↗

This function fills in the 'WITNESS' nodes of a 'dag' with the data from 'witness'. * For each 'WITNESS' : A |- B expression in 'dag', the bits from the 'witness' bitstring are decoded in turn * to construct a compact representation of a witness value of type B. * If there are not enough bits, then 'SIMPLICITY_ERR_WITNESS_EOF' is returned. * If a witness node would end up with more than CELLS_

Source from the content-addressed store, hash-verified

482 * when the result is 'SIMPLICITY_NO_ERROR';
483 */
484simplicity_err simplicity_fillWitnessData(dag_node* dag, type* type_dag, const uint_fast32_t len, bitstream *witness) {
485 static_assert(CELLS_MAX <= 0x80000000, "CELLS_MAX is too large.");
486 for (uint_fast32_t i = 0; i < len; ++i) {
487 if (WITNESS == dag[i].tag) {
488 if (CELLS_MAX < type_dag[WITNESS_B(dag, type_dag, i)].bitSize) return SIMPLICITY_ERR_EXEC_MEMORY;
489 if (witness->len <= 0) {
490 /* There is no data in the witness. */
491 dag[i].compactValue = (bitstring){0};
492 /* This is fine as long as the witness type is trivial */
493 if (type_dag[WITNESS_B(dag, type_dag, i)].bitSize) return SIMPLICITY_ERR_WITNESS_EOF;
494 } else {
495 dag[i].compactValue = (bitstring)
496 { .arr = witness->arr
497 , .offset = witness->offset
498 , .len = 0 /* The value of .len will computed within the while loop. */
499 };
500
501 /* Traverse the witness type to parse the witness's compact representation as a bit string. */
502 size_t cur = typeSkip(WITNESS_B(dag, type_dag, i), type_dag);
503 bool calling = true;
504 setTypeBack(cur, type_dag, 0);
505 while (cur) {
506 if (SUM == type_dag[cur].kind) {
507 /* Parse one bit and traverse the left type or the right type depending on the value of the bit parsed. */
508 simplicity_assert(calling);
509 int32_t bit = read1Bit(witness);
510 if (bit < 0) return SIMPLICITY_ERR_WITNESS_EOF;
511 dag[i].compactValue.len++;
512 size_t next = typeSkip(type_dag[cur].typeArg[bit], type_dag);
513 if (next) {
514 setTypeBack(next, type_dag, type_dag[cur].back);
515 cur = next;
516 } else {
517 cur = type_dag[cur].back;
518 calling = false;
519 }
520 } else {
521 simplicity_assert(PRODUCT == type_dag[cur].kind);
522 size_t next;
523 if (calling) {
524 next = typeSkip(type_dag[cur].typeArg[0], type_dag);
525 /* Note: Because we are using 'typeSkip' we have an invarant on 'cur' such that whenever type_dag[cur].kind == PRODUCT,
526 then it is a product of two non-trival types. This implies that 'next' cannot actually be 0. */
527 if (next) {
528 /* Traverse the first element of the product type, if it has any data. */
529 setTypeBack(next, type_dag, cur);
530 cur = next;
531 continue;
532 }
533 }
534 next = typeSkip(type_dag[cur].typeArg[1], type_dag);
535 /* Note: Because we are using 'typeSkip' we have an invarant on 'cur' such that whenever type_dag[cur].kind == PRODUCT,
536 then it is a product of two non-trival types. This implies that 'next' cannot actually be 0. */
537 if (next) {
538 /* Traverse the second element of the product type, if it has any data. */
539 setTypeBack(next, type_dag, type_dag[cur].back);
540 cur = next;
541 calling = true;

Callers 5

test_hashBlockFunction · 0.85
test_programFunction · 0.85
exactBudget_testFunction · 0.85

Calls 4

WITNESS_BFunction · 0.85
typeSkipFunction · 0.85
setTypeBackFunction · 0.85
read1BitFunction · 0.85

Tested by 4

test_hashBlockFunction · 0.68
test_programFunction · 0.68
exactBudget_testFunction · 0.68