File size: 2,320 Bytes
bc9e092
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
"""Read-only complete-EOF checks for the exact private HF asset manifest."""
import argparse,hashlib,json,os,stat
from pathlib import Path,PurePosixPath
MANIFEST_SHA256='24ee03260281cc1cbea9555b8d6ae695941bde55ac9fdad77682205615c9cb5d'
def verify_one(root,relative,expected):
 parts=PurePosixPath(relative).parts
 if not parts or relative.startswith('/') or '..' in parts or str(PurePosixPath(relative))!=relative:raise ValueError('Unsafe asset path')
 fd=os.open(root,os.O_RDONLY|os.O_DIRECTORY|os.O_NOFOLLOW)
 try:
  for part in parts[:-1]:
   nxt=os.open(part,os.O_RDONLY|os.O_DIRECTORY|os.O_NOFOLLOW,dir_fd=fd);os.close(fd);fd=nxt
  src=os.open(parts[-1],os.O_RDONLY|os.O_NOFOLLOW,dir_fd=fd)
  with os.fdopen(src,'rb') as f:
   before=os.fstat(f.fileno())
   if not stat.S_ISREG(before.st_mode) or before.st_size!=expected['bytes']:raise ValueError('Asset type/size differs: '+relative)
   h=hashlib.sha256();n=0
   while chunk:=f.read(8*1024*1024):h.update(chunk);n+=len(chunk)
   after=os.fstat(f.fileno())
   keys=('st_dev','st_ino','st_mode','st_size','st_mtime_ns','st_ctime_ns')
   if any(getattr(before,k)!=getattr(after,k) for k in keys):raise ValueError('Asset changed while reading: '+relative)
   if n!=expected['bytes'] or h.hexdigest()!=expected['sha256']:raise ValueError('Asset EOF identity differs: '+relative)
   return {'repo_path':relative,'bytes':n,'sha256':h.hexdigest(),'full_eof':True}
 finally:os.close(fd)
def verify(root,manifest):
 b=Path(manifest).read_bytes()
 if hashlib.sha256(b).hexdigest()!=MANIFEST_SHA256:raise ValueError('Unreviewed asset manifest')
 m=json.loads(b)
 if m['schema']!='segment-private-hf-serving-assets/1' or m['counts']['total']!=50 or len(m['assets'])!=50:raise ValueError('Manifest scope')
 rows=[verify_one(Path(root),r['repo_path'],r) for r in m['assets']]
 return {'schema':'segment-private-hf-local-assets-eof/1','manifest_sha256':MANIFEST_SHA256,'files':rows,'total_bytes':sum(r['bytes'] for r in rows),'all_complete':True,'scope':'Local model/prior byte identity only; no model execution, upload or access proof.'}
def main():
 p=argparse.ArgumentParser();p.add_argument('--root',required=True);p.add_argument('--manifest',required=True);a=p.parse_args();print(json.dumps(verify(a.root,a.manifest),sort_keys=True,indent=2))
if __name__=='__main__':main()