github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/tests/rlp_test_util.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 // 10 // 11 // 12 // 13 // 14 // 15 // 16 // 17 // 18 // 19 // 20 // 21 // 22 // 23 // 24 25 package tests 26 27 import ( 28 "bytes" 29 "encoding/hex" 30 "errors" 31 "fmt" 32 "math/big" 33 "strings" 34 35 "github.com/ethereum/go-ethereum/rlp" 36 ) 37 38 // 39 type RLPTest struct { 40 // 41 // 42 // 43 // 44 // 45 // 46 // 47 In interface{} 48 49 // 50 Out string 51 } 52 53 // 54 func (t *RLPTest) Run() error { 55 outb, err := hex.DecodeString(t.Out) 56 if err != nil { 57 return fmt.Errorf("invalid hex in Out") 58 } 59 60 // 61 if t.In == "VALID" || t.In == "INVALID" { 62 return checkDecodeInterface(outb, t.In == "VALID") 63 } 64 65 // 66 in := translateJSON(t.In) 67 b, err := rlp.EncodeToBytes(in) 68 if err != nil { 69 return fmt.Errorf("encode failed: %v", err) 70 } 71 if !bytes.Equal(b, outb) { 72 return fmt.Errorf("encode produced %x, want %x", b, outb) 73 } 74 // 75 s := rlp.NewStream(bytes.NewReader(outb), 0) 76 return checkDecodeFromJSON(s, in) 77 } 78 79 func checkDecodeInterface(b []byte, isValid bool) error { 80 err := rlp.DecodeBytes(b, new(interface{})) 81 switch { 82 case isValid && err != nil: 83 return fmt.Errorf("decoding failed: %v", err) 84 case !isValid && err == nil: 85 return fmt.Errorf("decoding of invalid value succeeded") 86 } 87 return nil 88 } 89 90 // 91 func translateJSON(v interface{}) interface{} { 92 switch v := v.(type) { 93 case float64: 94 return uint64(v) 95 case string: 96 if len(v) > 0 && v[0] == '#' { // 97 big, ok := new(big.Int).SetString(v[1:], 10) 98 if !ok { 99 panic(fmt.Errorf("bad test: bad big int: %q", v)) 100 } 101 return big 102 } 103 return []byte(v) 104 case []interface{}: 105 new := make([]interface{}, len(v)) 106 for i := range v { 107 new[i] = translateJSON(v[i]) 108 } 109 return new 110 default: 111 panic(fmt.Errorf("can't handle %T", v)) 112 } 113 } 114 115 // 116 // 117 // 118 // 119 func checkDecodeFromJSON(s *rlp.Stream, exp interface{}) error { 120 switch exp := exp.(type) { 121 case uint64: 122 i, err := s.Uint() 123 if err != nil { 124 return addStack("Uint", exp, err) 125 } 126 if i != exp { 127 return addStack("Uint", exp, fmt.Errorf("result mismatch: got %d", i)) 128 } 129 case *big.Int: 130 big := new(big.Int) 131 if err := s.Decode(&big); err != nil { 132 return addStack("Big", exp, err) 133 } 134 if big.Cmp(exp) != 0 { 135 return addStack("Big", exp, fmt.Errorf("result mismatch: got %d", big)) 136 } 137 case []byte: 138 b, err := s.Bytes() 139 if err != nil { 140 return addStack("Bytes", exp, err) 141 } 142 if !bytes.Equal(b, exp) { 143 return addStack("Bytes", exp, fmt.Errorf("result mismatch: got %x", b)) 144 } 145 case []interface{}: 146 if _, err := s.List(); err != nil { 147 return addStack("List", exp, err) 148 } 149 for i, v := range exp { 150 if err := checkDecodeFromJSON(s, v); err != nil { 151 return addStack(fmt.Sprintf("[%d]", i), exp, err) 152 } 153 } 154 if err := s.ListEnd(); err != nil { 155 return addStack("ListEnd", exp, err) 156 } 157 default: 158 panic(fmt.Errorf("unhandled type: %T", exp)) 159 } 160 return nil 161 } 162 163 func addStack(op string, val interface{}, err error) error { 164 lines := strings.Split(err.Error(), "\n") 165 lines = append(lines, fmt.Sprintf("\t%s: %v", op, val)) 166 return errors.New(strings.Join(lines, "\n")) 167 }