- Started in `ProcessNewBlock`, `main.cpp:4258` - Calls `CheckBlock`, defined at https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/main.cpp#L3930 - Calls `CheckBlockHeader` https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/main.cpp#L3900 - checks that the block version is not too old - this requires no information - checks that the equihash solution is valid - https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/pow.cpp#L96 - requires no information except `n`, `k` params - checks that the proof of work parameters are valid - requires the current proof of work amount `params.powLimit` - Checks the Merkle root - Checks size limits - Checks that the first transaction is coinbase, and the rest are not - Calls `CheckTransaction` for each transaction, defined at: https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/main.cpp#L1056 - is coinbase - calls `CheckTransactionWithoutProofVerification`, defined at: https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/main.cpp#L1078 - 'Basic checks that don't require any context' - With verifier == false, it looks like in this flow - Checks a whole bunch of stuff that we check with our semantic representation into structs - We should double check that there are no conditions on the values and amounts that we aren't already checking - Check for duplicate - inputs - nullifiers (within a single transaction) - // Transactions containing empty `vin` must have either non-empty `vJoinSplit` or non-empty `vShieldedSpend`. - // Transactions containing empty `vout` must have either non-empty `vJoinSplit` or non-empty `vShieldedOutput`. - Moar: https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/main.cpp#L1091 - Sum up "LegacySigOps" for each transaction and check that it's less than some maximum - Acquires a lock, then calls `MarkBlockAsReceived` (networking?) - Calls `AcceptBlock`, defined at: https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/main.cpp#L4180 - Calls `AcceptBlockHeader`, defined at: https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/main.cpp#L4130 - Also calls `CheckBlockHeader` - Calls `ContextualCheckBlockHeader`, defined at: https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/main.cpp#L3900 - Does checks given a pointer to the previous block - Check Equihash solution is valid - In our code we compute the equihash solution on the block alone, we will need to also do a step to check that its block height is the appopriate N+1 re: the previous block - Check proof of work - Check timestamp against prev - Check future timestamp soft fork rule introduced in v2.1.1-1. - https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/main.cpp#L4027 - Check timestamp - https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/main.cpp#L4040 - Reject block.nVersion < 4 blocks - Don't accept any forks from the main chain prior to last checkpoint - We will probably get this 'more naturally' and don't need to explicitly check it like this - Calls `CheckBlock` also, w/ ProofVerifier::Disabled == true - https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/main.cpp#L4211 - Calls `ContextualCheckBlock`, defined at https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/main.cpp#L4065 - For each transaction: - Calls `ContextualCheckTransaction`, defined at https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/main.cpp#L760 - For Zebra, we should only be doing Transaction v4 (Sapling+) checks, because checkpointing - If we reach a point where we are doing contextual transaction validation for the other types, abort - Check that all transactions are unexpired - A coinbase transaction cannot have output descriptions - All Sapling outputs in coinbase transactions MUST have valid note commitments when recovered using a 32-byte array of zeroes as the outgoing viewing key. https://zips.z.cash/zip-0213#specification - Compute SigHash on data to be signed and _previous_ data to be signed - Check joinsplit signature on data to be signed - If fail, check on previous data to be signed : https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/main.cpp#L971 - Check Spend/Output Descriptions - Check Spends: https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/main.cpp#L998 - Check Outputs: https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/main.cpp#L1018 - Check final balances: https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/main.cpp#L1036 - Calls `IsFinalTx`, defined at https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/main.cpp#L675 - Calls tx::IsFinal(): https://github.com/zcash/zcash/blob/6d9573c66e33b5b742c49ab35e816d74d4ab55b1/src/primitives/transaction.h#L401 - Enforce BIP 34: https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/main.cpp#L4090 - If blockheight < the block just before the first subsidy halving block, dispense Founder's Reward: https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/main.cpp#L4104 - Everything else is state/index management after good verification - Calls `CheckBlockIndex`, defined at https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/main.cpp#L5125 - Calls `ActivateBestChain`, defined at https://github.com/zcash/zcash/blob/ab2b7c0969391d8a57d90d008665da02f3f618e7/src/main.cpp#L3513