The problem with your idea is its practicality otherwise it is pretty trivial to implement.
Normally you don't know
when exactly you've received bitcoin and
when exactly you've spent those coins. Even knowing a range is not going to help much because you'd have to download roughly 6 blocks per hour or 144 blocks per day which is high enough for a light client.
So the idea is to download (apart from the complete block header list) only the blocks in the periods I'm interested, and search for transactions involving my keys/addresses in them. (The correctness of the blocks depends on the source of my block header list of course, so minimal trust would still be required.)
There is no trust needed, just knowing that you are on the correct chain which is easy to do. You basically have to play around in the
net_processing part of bitcoin core:
Step 1:Initial connection is the same as a full node, fetching a list from seed nodes and building a listening node IP address database for future usages using the
getaddr and
addr messages.
Step 2:Exactly as a full node, start by downloading the blockheader list from the hard-coded Genesis block to the tip from multiple different nodes with enough distance that makes it safe. You can also add hard-coded checkpoints to add an additional verification for the "map" of the chain you are downloading.
You can also do full verification on these headers just like a full node does (SPV clients should also do this). The verification includes version verification, PoW verification using the header hash and the shortened target in the header, difficulty verification with the target and finally time verifications.
The network messages involved are:
version+
verack (handshake),
sendheaders,
getheaders, and
ping pong messages.
Step 3:Now that you have a "map" of the whole blockchain use the time field in the headers to select the block(s) you want to download then send a
getdata message (with the inventory set to block type and the hash(es) of the block(s) you want to download) to any full node from your connection list to download the full block from that node.
Then you can perform a limited verification on the block you received to make sure it is "correct". The important ones are deserializing and merkle root hash. This way you make sure all the transactions in the block you requested are received correctly and are associated with the header you requested. Here we rely on PoW and SHA256 both being secure.
Step 4:Now that you have a block that you are sure is "correct" with the trust you put in the PoW, you can go through the inputs and outputs of each tx to see which one belongs to you and update your balance accordingly.