Currently, block headers contain a flat hash (not a Merkle tree) of the transactions that appear in that block, but switching this to a Merkle tree would not be sufficient to allow for SPV.
For a precise (but rather dense) description of the structure of a block, you can check out the ledger specification at https://github.com/algorandfoundation/specs/tree/master/dev/ledger.md. Relevant to your question are sections 1.3 and 10.2.
(Here’s a compiled PDF version of the ledger spec, current as of 2019-11-21.)
It’s also worth looking at data/bookkeeping/block.go
where Block is defined in the code.
Unfortunately SPV for Algorand is somewhat more complicated than it is for Bitcoin because of how the proof-of-stake works.
With Bitcoin, a full node can send an SPV node all the block headers, and the SPV node can check the proof of work to ensure that these are (probably) the correct block headers. Then the full node can send the SPV node a Merkle proof that a transaction appeared in a particular block, and the SPV node can check the proof against the block header it already has and knows is correct.
Algorand doesn’t use proof of work – if I send you all the block headers, that on its own isn’t enough for you to know whether any of the block headers are correct. Algorand agrees on blocks via a Byzantine consensus protocol – with each block, there’s a set of votes (called a certificate) that proves that that block is correct.
This on its own isn’t a problem – the full node can just send certificates along with the block headers. And this would be enough if Algorand voters weren’t weighted by stake but instead came from some fixed list known in advance. But Algorand is permissionless and weighted by stake – in order to verify a vote, you need to know the voter’s balance as of some round shortly before the vote. (For technical reasons, votes for round R
are weighted by stake as of round R - 320
)
In particular, a certificate for round R
I send you can’t be verified unless you know the balances as of round R-320
and to know the correct balances in round R-320
you’d at the very least need to have block R-320
. But to make sure you have the correct block R-320
you’ll need to verify its certificate, which requires knowing the balances in round R-640
, and so on.
Since an SPV client wouldn’t want to download all the balances, we could make every block commit to that round’s balances in, say, a giant Merkle tree and put the commitment in the block header. (The balance tree needs to be efficiently updatable because recomputing a Merkle root of all balances in the system from scratch every block would be too slow, but there are ways of structuring the tree to make this possible.) Then we can include with every certificate the Merkle paths to the balances of the voters in that certificate.
This would help, but the bandwidth cost for the SPV client is still considerable – if the system has many accounts and Merkle paths are long, the added overhead of sending a Merkle path for every voter in a certificate is significant.
There are a few further optimizations that can further reduce the bandwidth cost; there are also a few complications that I’m ignoring in the above description. If you’re interested, this is what the Vault paper is about. (https://eprint.iacr.org/2018/269, see also slides at https://www.ndss-symposium.org/wp-content/uploads/ndss2019_09-2_Leung_slides.pdf) Vault goes a little bit further and also describes how to allow full participating nodes to store less than the full set of balances (“sharding”), but that part isn’t needed for SPV.
Again, because of the way we do proof-of-stake, some sort of bootstrapping process like this is fundamentally necessary – there’s no escaping the fact that you can’t trust a block header without already being able to trust a recent set of balances, and you can’t trust those balances without at least a trustworthy block header. So an SPV client needs to download and validate lots of certificates, and certificates are way larger than block headers. For Bitcoin, which is proof-of-work, it suffices to look only at block headers – no certificates, no efficiently-updatable commitments to the entire set of balances.
So yes, we definitely want to have an Electrum-like SPV client, but for us it’s inherently more complicated than for Bitcoin, so implementing it is going to be a decent amount of work.