github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/tools/sigchain/main.go (about)

     1  package main
     2  
     3  import (
     4  	"flag"
     5  	"fmt"
     6  	"io"
     7  	"log"
     8  	"os"
     9  	"runtime"
    10  	"runtime/pprof"
    11  	"time"
    12  
    13  	"github.com/keybase/client/go/libkb"
    14  	"github.com/keybase/client/go/logger"
    15  	"github.com/keybase/client/go/protocol/keybase1"
    16  )
    17  
    18  var uid = flag.String("uid", "", "uid of sigchain owner")
    19  var username = flag.String("username", "", "username of sigchain owner")
    20  var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
    21  
    22  func errout(msg string) {
    23  	fmt.Fprintf(os.Stderr, msg+"\n")
    24  	os.Exit(1)
    25  }
    26  
    27  func read() []byte {
    28  	var in io.Reader
    29  	switch flag.NArg() {
    30  	case 0:
    31  		fmt.Println("reading sigchain from stdin")
    32  		in = os.Stdin
    33  	case 1:
    34  		fmt.Printf("reading sigchain from %q\n", flag.Arg(0))
    35  		f, err := os.Open(flag.Arg(0))
    36  		if err != nil {
    37  			errout(err.Error())
    38  		}
    39  		defer f.Close()
    40  		in = f
    41  	default:
    42  		errout("provide 0 or 1 args")
    43  	}
    44  
    45  	all, err := io.ReadAll(in)
    46  	if err != nil {
    47  		errout(err.Error())
    48  	}
    49  	fmt.Printf("%d bytes read\n", len(all))
    50  	return all
    51  }
    52  
    53  func memstats() {
    54  	runtime.GC()
    55  	var ms runtime.MemStats
    56  	runtime.ReadMemStats(&ms)
    57  	fmt.Printf("Alloc: %d (%d KB) (%d MB)\n", ms.Alloc, ms.Alloc/1024, ms.Alloc/(1024*1024))
    58  	fmt.Printf("TotalAlloc: %d (%d KB) (%d MB)\n", ms.TotalAlloc, ms.TotalAlloc/1024, ms.TotalAlloc/(1024*1024))
    59  }
    60  
    61  func memprof() {
    62  	f, err := os.Create("/tmp/sc_memprof")
    63  	if err != nil {
    64  		log.Fatal("could not create memory profile: ", err)
    65  	}
    66  	runtime.GC() // get up-to-date statistics
    67  	if err := pprof.WriteHeapProfile(f); err != nil {
    68  		log.Fatal("could not write memory profile: ", err)
    69  	}
    70  	f.Close()
    71  	fmt.Printf("wrote memory profile to /tmp/sc_memprof\n")
    72  }
    73  
    74  // don't GC me
    75  var sc *libkb.SigChain
    76  
    77  func main() {
    78  	fmt.Println("sigchain loader")
    79  	flag.Parse()
    80  	raw := read()
    81  
    82  	g := libkb.NewGlobalContext().Init()
    83  	g.Log = logger.New("sc")
    84  	if err := g.ConfigureCaches(); err != nil {
    85  		errout(err.Error())
    86  	}
    87  
    88  	iterations := 1
    89  	if *cpuprofile != "" {
    90  		f, err := os.Create(*cpuprofile)
    91  		if err != nil {
    92  			log.Fatal(err)
    93  		}
    94  		if err := pprof.StartCPUProfile(f); err != nil {
    95  			errout(err.Error())
    96  		}
    97  		defer pprof.StopCPUProfile()
    98  
    99  		iterations = 10
   100  	}
   101  
   102  	m := libkb.NewMetaContextBackground(g)
   103  
   104  	for i := 0; i < iterations; i++ {
   105  		start := time.Now()
   106  		sc = &libkb.SigChain{Contextified: libkb.NewContextified(g)}
   107  		sc.SetUIDUsername(keybase1.UID(*uid), *username)
   108  		if _, err := sc.LoadServerBody(m, raw, 0, nil, ""); err != nil {
   109  			errout(err.Error())
   110  		}
   111  
   112  		if err := sc.VerifyChain(m, keybase1.UID(*uid)); err != nil {
   113  			errout(err.Error())
   114  		}
   115  
   116  		if err := sc.Store(m); err != nil {
   117  			errout(err.Error())
   118  		}
   119  		elapsed := time.Since(start)
   120  		fmt.Printf("sig chain load time: %s\n", elapsed)
   121  	}
   122  
   123  	memstats()
   124  	memprof()
   125  }