mirror of https://github.com/poanetwork/gecko.git
Implemented fx operations
This commit is contained in:
parent
93ff9d906b
commit
ffcdfafaf6
|
@ -288,32 +288,166 @@ func Genesis(networkID uint32) []byte {
|
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x05, 0x00, 0x00, 0x30, 0x39, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
||||
0x41, 0x56, 0x4d, 0x61, 0x76, 0x6d, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
|
||||
0x58, 0x2d, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x61,
|
||||
0x76, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x73,
|
||||
0x65, 0x63, 0x70, 0x32, 0x35, 0x36, 0x6b, 0x31,
|
||||
0x66, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x73, 0x65, 0x63, 0x70, 0x32,
|
||||
0x35, 0x36, 0x6b, 0x31, 0x66, 0x78, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x03, 0x41, 0x56, 0x41, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x03, 0x41, 0x56, 0x41,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x03, 0x41, 0x56, 0x41, 0x00, 0x03, 0x41,
|
||||
0x56, 0x41, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x06, 0x00, 0x9f, 0xdf, 0x42, 0xf6,
|
||||
0xe4, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x01, 0x3c, 0xb7, 0xd3, 0x84, 0x2e,
|
||||
0x8c, 0xee, 0x6a, 0x0e, 0xbd, 0x09, 0xf1, 0xfe,
|
||||
0x88, 0x4f, 0x68, 0x61, 0xe1, 0xb2, 0x9c, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x41, 0x56,
|
||||
0x41, 0x00, 0x03, 0x41, 0x56, 0x41, 0x09, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00,
|
||||
0x9f, 0xdf, 0x42, 0xf6, 0xe4, 0x80, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x3c,
|
||||
0xb7, 0xd3, 0x84, 0x2e, 0x8c, 0xee, 0x6a, 0x0e,
|
||||
0xbd, 0x09, 0xf1, 0xfe, 0x88, 0x4f, 0x68, 0x61,
|
||||
0xe1, 0xb2, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x07, 0x43, 0x2d, 0x43, 0x68, 0x61, 0x69,
|
||||
0x6e, 0x65, 0x76, 0x6d, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
|
||||
0xc9, 0x7b, 0x22, 0x63, 0x6f, 0x6e, 0x66, 0x69,
|
||||
0x67, 0x22, 0x3a, 0x7b, 0x22, 0x63, 0x68, 0x61,
|
||||
0x69, 0x6e, 0x49, 0x64, 0x22, 0x3a, 0x34, 0x33,
|
||||
0x31, 0x31, 0x30, 0x2c, 0x22, 0x68, 0x6f, 0x6d,
|
||||
0x65, 0x73, 0x74, 0x65, 0x61, 0x64, 0x42, 0x6c,
|
||||
0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22,
|
||||
0x64, 0x61, 0x6f, 0x46, 0x6f, 0x72, 0x6b, 0x42,
|
||||
0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c,
|
||||
0x22, 0x64, 0x61, 0x6f, 0x46, 0x6f, 0x72, 0x6b,
|
||||
0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x22,
|
||||
0x3a, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x22, 0x65,
|
||||
0x69, 0x70, 0x31, 0x35, 0x30, 0x42, 0x6c, 0x6f,
|
||||
0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x65,
|
||||
0x69, 0x70, 0x31, 0x35, 0x30, 0x48, 0x61, 0x73,
|
||||
0x68, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x32, 0x30,
|
||||
0x38, 0x36, 0x37, 0x39, 0x39, 0x61, 0x65, 0x65,
|
||||
0x62, 0x65, 0x61, 0x65, 0x31, 0x33, 0x35, 0x63,
|
||||
0x32, 0x34, 0x36, 0x63, 0x36, 0x35, 0x30, 0x32,
|
||||
0x31, 0x63, 0x38, 0x32, 0x62, 0x34, 0x65, 0x31,
|
||||
0x35, 0x61, 0x32, 0x63, 0x34, 0x35, 0x31, 0x33,
|
||||
0x34, 0x30, 0x39, 0x39, 0x33, 0x61, 0x61, 0x63,
|
||||
0x66, 0x64, 0x32, 0x37, 0x35, 0x31, 0x38, 0x38,
|
||||
0x36, 0x35, 0x31, 0x34, 0x66, 0x30, 0x22, 0x2c,
|
||||
0x22, 0x65, 0x69, 0x70, 0x31, 0x35, 0x35, 0x42,
|
||||
0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c,
|
||||
0x22, 0x65, 0x69, 0x70, 0x31, 0x35, 0x38, 0x42,
|
||||
0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c,
|
||||
0x22, 0x62, 0x79, 0x7a, 0x61, 0x6e, 0x74, 0x69,
|
||||
0x75, 0x6d, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22,
|
||||
0x3a, 0x30, 0x2c, 0x22, 0x63, 0x6f, 0x6e, 0x73,
|
||||
0x74, 0x61, 0x6e, 0x74, 0x69, 0x6e, 0x6f, 0x70,
|
||||
0x6c, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22,
|
||||
0x3a, 0x30, 0x2c, 0x22, 0x70, 0x65, 0x74, 0x65,
|
||||
0x72, 0x73, 0x62, 0x75, 0x72, 0x67, 0x42, 0x6c,
|
||||
0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x7d, 0x2c,
|
||||
0x22, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x22, 0x3a,
|
||||
0x22, 0x30, 0x78, 0x30, 0x22, 0x2c, 0x22, 0x74,
|
||||
0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
|
||||
0x22, 0x3a, 0x22, 0x30, 0x78, 0x30, 0x22, 0x2c,
|
||||
0x22, 0x65, 0x78, 0x74, 0x72, 0x61, 0x44, 0x61,
|
||||
0x74, 0x61, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x30,
|
||||
0x30, 0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x4c,
|
||||
0x69, 0x6d, 0x69, 0x74, 0x22, 0x3a, 0x22, 0x30,
|
||||
0x78, 0x35, 0x66, 0x35, 0x65, 0x31, 0x30, 0x30,
|
||||
0x22, 0x2c, 0x22, 0x64, 0x69, 0x66, 0x66, 0x69,
|
||||
0x63, 0x75, 0x6c, 0x74, 0x79, 0x22, 0x3a, 0x22,
|
||||
0x30, 0x78, 0x30, 0x22, 0x2c, 0x22, 0x6d, 0x69,
|
||||
0x78, 0x48, 0x61, 0x73, 0x68, 0x22, 0x3a, 0x22,
|
||||
0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x22, 0x2c, 0x22, 0x63, 0x6f, 0x69,
|
||||
0x6e, 0x62, 0x61, 0x73, 0x65, 0x22, 0x3a, 0x22,
|
||||
0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x22, 0x2c, 0x22, 0x61, 0x6c, 0x6c,
|
||||
0x6f, 0x63, 0x22, 0x3a, 0x7b, 0x22, 0x37, 0x35,
|
||||
0x31, 0x61, 0x30, 0x62, 0x39, 0x36, 0x65, 0x31,
|
||||
0x30, 0x34, 0x32, 0x62, 0x65, 0x65, 0x37, 0x38,
|
||||
0x39, 0x34, 0x35, 0x32, 0x65, 0x63, 0x62, 0x32,
|
||||
0x30, 0x32, 0x35, 0x33, 0x66, 0x62, 0x61, 0x34,
|
||||
0x30, 0x64, 0x62, 0x65, 0x38, 0x35, 0x22, 0x3a,
|
||||
0x7b, 0x22, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63,
|
||||
0x65, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x33, 0x33,
|
||||
0x62, 0x32, 0x65, 0x33, 0x63, 0x39, 0x66, 0x64,
|
||||
0x30, 0x38, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x7d, 0x7d,
|
||||
0x2c, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72,
|
||||
0x22, 0x3a, 0x22, 0x30, 0x78, 0x30, 0x22, 0x2c,
|
||||
0x22, 0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64,
|
||||
0x22, 0x3a, 0x22, 0x30, 0x78, 0x30, 0x22, 0x2c,
|
||||
0x22, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x48,
|
||||
0x61, 0x73, 0x68, 0x22, 0x3a, 0x22, 0x30, 0x78,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x22, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x13, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20,
|
||||
0x44, 0x41, 0x47, 0x20, 0x50, 0x61, 0x79, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x73, 0x73, 0x70, 0x64, 0x61,
|
||||
0x67, 0x76, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x02,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x30,
|
||||
0x9c, 0xe5, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x01, 0x3c, 0xb7, 0xd3, 0x84,
|
||||
0x2e, 0x8c, 0xee, 0x6a, 0x0e, 0xbd, 0x09, 0xf1,
|
||||
0xfe, 0x88, 0x4f, 0x68, 0x61, 0xe1, 0xb2, 0x9c,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
@ -322,103 +456,21 @@ func Genesis(networkID uint32) []byte {
|
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x41, 0x74,
|
||||
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x65, 0x76,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
|
||||
0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x15, 0x53, 0x69, 0x6d, 0x70, 0x6c,
|
||||
0x65, 0x20, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x20,
|
||||
0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73,
|
||||
0x73, 0x70, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x76,
|
||||
0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
|
||||
0x00, 0x00, 0x00, 0x01, 0x3c, 0xb7, 0xd3, 0x84,
|
||||
0x2e, 0x8c, 0xee, 0x6a, 0x0e, 0xbd, 0x09, 0xf1,
|
||||
0xfe, 0x88, 0x4f, 0x68, 0x61, 0xe1, 0xb2, 0x9c,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0xc9, 0x7b, 0x22,
|
||||
0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x3a,
|
||||
0x7b, 0x22, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49,
|
||||
0x64, 0x22, 0x3a, 0x34, 0x33, 0x31, 0x31, 0x30,
|
||||
0x2c, 0x22, 0x68, 0x6f, 0x6d, 0x65, 0x73, 0x74,
|
||||
0x65, 0x61, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b,
|
||||
0x22, 0x3a, 0x30, 0x2c, 0x22, 0x64, 0x61, 0x6f,
|
||||
0x46, 0x6f, 0x72, 0x6b, 0x42, 0x6c, 0x6f, 0x63,
|
||||
0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x64, 0x61,
|
||||
0x6f, 0x46, 0x6f, 0x72, 0x6b, 0x53, 0x75, 0x70,
|
||||
0x70, 0x6f, 0x72, 0x74, 0x22, 0x3a, 0x74, 0x72,
|
||||
0x75, 0x65, 0x2c, 0x22, 0x65, 0x69, 0x70, 0x31,
|
||||
0x35, 0x30, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22,
|
||||
0x3a, 0x30, 0x2c, 0x22, 0x65, 0x69, 0x70, 0x31,
|
||||
0x35, 0x30, 0x48, 0x61, 0x73, 0x68, 0x22, 0x3a,
|
||||
0x22, 0x30, 0x78, 0x32, 0x30, 0x38, 0x36, 0x37,
|
||||
0x39, 0x39, 0x61, 0x65, 0x65, 0x62, 0x65, 0x61,
|
||||
0x65, 0x31, 0x33, 0x35, 0x63, 0x32, 0x34, 0x36,
|
||||
0x63, 0x36, 0x35, 0x30, 0x32, 0x31, 0x63, 0x38,
|
||||
0x32, 0x62, 0x34, 0x65, 0x31, 0x35, 0x61, 0x32,
|
||||
0x63, 0x34, 0x35, 0x31, 0x33, 0x34, 0x30, 0x39,
|
||||
0x39, 0x33, 0x61, 0x61, 0x63, 0x66, 0x64, 0x32,
|
||||
0x37, 0x35, 0x31, 0x38, 0x38, 0x36, 0x35, 0x31,
|
||||
0x34, 0x66, 0x30, 0x22, 0x2c, 0x22, 0x65, 0x69,
|
||||
0x70, 0x31, 0x35, 0x35, 0x42, 0x6c, 0x6f, 0x63,
|
||||
0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x65, 0x69,
|
||||
0x70, 0x31, 0x35, 0x38, 0x42, 0x6c, 0x6f, 0x63,
|
||||
0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x62, 0x79,
|
||||
0x7a, 0x61, 0x6e, 0x74, 0x69, 0x75, 0x6d, 0x42,
|
||||
0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c,
|
||||
0x22, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e,
|
||||
0x74, 0x69, 0x6e, 0x6f, 0x70, 0x6c, 0x65, 0x42,
|
||||
0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c,
|
||||
0x22, 0x70, 0x65, 0x74, 0x65, 0x72, 0x73, 0x62,
|
||||
0x75, 0x72, 0x67, 0x42, 0x6c, 0x6f, 0x63, 0x6b,
|
||||
0x22, 0x3a, 0x30, 0x7d, 0x2c, 0x22, 0x6e, 0x6f,
|
||||
0x6e, 0x63, 0x65, 0x22, 0x3a, 0x22, 0x30, 0x78,
|
||||
0x30, 0x22, 0x2c, 0x22, 0x74, 0x69, 0x6d, 0x65,
|
||||
0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x3a, 0x22,
|
||||
0x30, 0x78, 0x30, 0x22, 0x2c, 0x22, 0x65, 0x78,
|
||||
0x74, 0x72, 0x61, 0x44, 0x61, 0x74, 0x61, 0x22,
|
||||
0x3a, 0x22, 0x30, 0x78, 0x30, 0x30, 0x22, 0x2c,
|
||||
0x22, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69,
|
||||
0x74, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x35, 0x66,
|
||||
0x35, 0x65, 0x31, 0x30, 0x30, 0x22, 0x2c, 0x22,
|
||||
0x64, 0x69, 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c,
|
||||
0x74, 0x79, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x30,
|
||||
0x22, 0x2c, 0x22, 0x6d, 0x69, 0x78, 0x48, 0x61,
|
||||
0x73, 0x68, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22,
|
||||
0x2c, 0x22, 0x63, 0x6f, 0x69, 0x6e, 0x62, 0x61,
|
||||
0x73, 0x65, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22,
|
||||
0x2c, 0x22, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x22,
|
||||
0x3a, 0x7b, 0x22, 0x37, 0x35, 0x31, 0x61, 0x30,
|
||||
0x62, 0x39, 0x36, 0x65, 0x31, 0x30, 0x34, 0x32,
|
||||
0x62, 0x65, 0x65, 0x37, 0x38, 0x39, 0x34, 0x35,
|
||||
0x32, 0x65, 0x63, 0x62, 0x32, 0x30, 0x32, 0x35,
|
||||
0x33, 0x66, 0x62, 0x61, 0x34, 0x30, 0x64, 0x62,
|
||||
0x65, 0x38, 0x35, 0x22, 0x3a, 0x7b, 0x22, 0x62,
|
||||
0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x3a,
|
||||
0x22, 0x30, 0x78, 0x33, 0x33, 0x62, 0x32, 0x65,
|
||||
0x33, 0x63, 0x39, 0x66, 0x64, 0x30, 0x38, 0x30,
|
||||
0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x22, 0x7d, 0x7d, 0x2c, 0x22, 0x6e,
|
||||
0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x3a, 0x22,
|
||||
0x30, 0x78, 0x30, 0x22, 0x2c, 0x22, 0x67, 0x61,
|
||||
0x73, 0x55, 0x73, 0x65, 0x64, 0x22, 0x3a, 0x22,
|
||||
0x30, 0x78, 0x30, 0x22, 0x2c, 0x22, 0x70, 0x61,
|
||||
0x72, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68,
|
||||
0x22, 0x3a, 0x22, 0x30, 0x78, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x7d, 0x00,
|
||||
0x00, 0x00, 0x12, 0x30, 0x9c, 0xe5, 0x40, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
@ -427,64 +479,12 @@ func Genesis(networkID uint32) []byte {
|
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x53, 0x69,
|
||||
0x6d, 0x70, 0x6c, 0x65, 0x20, 0x44, 0x41, 0x47,
|
||||
0x20, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74,
|
||||
0x73, 0x73, 0x70, 0x64, 0x61, 0x67, 0x76, 0x6d,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x12, 0x30, 0x9c, 0xe5, 0x40,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x01, 0x3c, 0xb7, 0xd3, 0x84, 0x2e, 0x8c, 0xee,
|
||||
0x6a, 0x0e, 0xbd, 0x09, 0xf1, 0xfe, 0x88, 0x4f,
|
||||
0x68, 0x61, 0xe1, 0xb2, 0x9c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x30, 0x39, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
|
||||
0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43,
|
||||
0x68, 0x61, 0x69, 0x6e, 0x20, 0x50, 0x61, 0x79,
|
||||
0x6d, 0x65, 0x6e, 0x74, 0x73, 0x73, 0x70, 0x63,
|
||||
0x68, 0x61, 0x69, 0x6e, 0x76, 0x6d, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
|
||||
0x01, 0x3c, 0xb7, 0xd3, 0x84, 0x2e, 0x8c, 0xee,
|
||||
0x6a, 0x0e, 0xbd, 0x09, 0xf1, 0xfe, 0x88, 0x4f,
|
||||
0x68, 0x61, 0xe1, 0xb2, 0x9c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
|
||||
0x30, 0x9c, 0xe5, 0x40, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x30, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x17, 0x53, 0x69, 0x6d, 0x70,
|
||||
0x6c, 0x65, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x73,
|
||||
0x74, 0x61, 0x6d, 0x70, 0x20, 0x53, 0x65, 0x72,
|
||||
0x76, 0x65, 0x72, 0x74, 0x69, 0x6d, 0x65, 0x73,
|
||||
0x74, 0x61, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x53,
|
||||
0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x54, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20,
|
||||
0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x74, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
@ -497,7 +497,7 @@ func Genesis(networkID uint32) []byte {
|
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x5d, 0xbb, 0x75, 0x80,
|
||||
0x00, 0x00, 0x00, 0x5d, 0xbb, 0x75, 0x80,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -527,10 +527,10 @@ func AVAAssetID(networkID uint32) ids.ID {
|
|||
c.RegisterType(&avm.OperationTx{})
|
||||
c.RegisterType(&avm.ImportTx{})
|
||||
c.RegisterType(&avm.ExportTx{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOutput{})
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{})
|
||||
c.RegisterType(&secp256k1fx.MintInput{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOperation{})
|
||||
c.RegisterType(&secp256k1fx.Credential{})
|
||||
|
||||
genesis := avm.Genesis{}
|
||||
|
|
|
@ -55,6 +55,9 @@ func (t *BaseTx) AssetIDs() ids.Set {
|
|||
return assets
|
||||
}
|
||||
|
||||
// NumCredentials returns the number of expected credentials
|
||||
func (t *BaseTx) NumCredentials() int { return len(t.Ins) }
|
||||
|
||||
// UTXOs returns the UTXOs transaction is producing.
|
||||
func (t *BaseTx) UTXOs() []*ava.UTXO {
|
||||
txID := t.ID()
|
||||
|
@ -139,7 +142,7 @@ func (t *BaseTx) SemanticVerify(vm *VM, uTx *UniqueTx, creds []verify.Verifiable
|
|||
return errIncompatibleFx
|
||||
}
|
||||
|
||||
if err := fx.VerifyTransfer(uTx, utxo.Out, in.In, cred); err != nil {
|
||||
if err := fx.VerifyTransfer(uTx, in.In, cred, utxo.Out); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ func TestBaseTxSerialization(t *testing.T) {
|
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// fxID:
|
||||
0x00, 0x00, 0x00, 0x04,
|
||||
0x00, 0x00, 0x00, 0x07,
|
||||
// secp256k1 Transferable Output:
|
||||
// amount:
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39,
|
||||
|
@ -66,7 +66,7 @@ func TestBaseTxSerialization(t *testing.T) {
|
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// fxID:
|
||||
0x00, 0x00, 0x00, 0x06,
|
||||
0x00, 0x00, 0x00, 0x05,
|
||||
// amount:
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31,
|
||||
// number of signatures:
|
||||
|
@ -112,10 +112,12 @@ func TestBaseTxSerialization(t *testing.T) {
|
|||
c.RegisterType(&BaseTx{})
|
||||
c.RegisterType(&CreateAssetTx{})
|
||||
c.RegisterType(&OperationTx{})
|
||||
c.RegisterType(&ImportTx{})
|
||||
c.RegisterType(&ExportTx{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOutput{})
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{})
|
||||
c.RegisterType(&secp256k1fx.MintInput{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOperation{})
|
||||
c.RegisterType(&secp256k1fx.Credential{})
|
||||
|
||||
b, err := c.Marshal(&tx.UnsignedTx)
|
||||
|
@ -187,10 +189,12 @@ func TestBaseTxSyntacticVerify(t *testing.T) {
|
|||
c.RegisterType(&BaseTx{})
|
||||
c.RegisterType(&CreateAssetTx{})
|
||||
c.RegisterType(&OperationTx{})
|
||||
c.RegisterType(&ImportTx{})
|
||||
c.RegisterType(&ExportTx{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOutput{})
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{})
|
||||
c.RegisterType(&secp256k1fx.MintInput{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOperation{})
|
||||
c.RegisterType(&secp256k1fx.Credential{})
|
||||
|
||||
tx := &BaseTx{
|
||||
|
@ -237,10 +241,12 @@ func TestBaseTxSyntacticVerifyNil(t *testing.T) {
|
|||
c.RegisterType(&BaseTx{})
|
||||
c.RegisterType(&CreateAssetTx{})
|
||||
c.RegisterType(&OperationTx{})
|
||||
c.RegisterType(&ImportTx{})
|
||||
c.RegisterType(&ExportTx{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOutput{})
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{})
|
||||
c.RegisterType(&secp256k1fx.MintInput{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOperation{})
|
||||
c.RegisterType(&secp256k1fx.Credential{})
|
||||
|
||||
tx := (*BaseTx)(nil)
|
||||
|
@ -254,10 +260,12 @@ func TestBaseTxSyntacticVerifyWrongNetworkID(t *testing.T) {
|
|||
c.RegisterType(&BaseTx{})
|
||||
c.RegisterType(&CreateAssetTx{})
|
||||
c.RegisterType(&OperationTx{})
|
||||
c.RegisterType(&ImportTx{})
|
||||
c.RegisterType(&ExportTx{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOutput{})
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{})
|
||||
c.RegisterType(&secp256k1fx.MintInput{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOperation{})
|
||||
c.RegisterType(&secp256k1fx.Credential{})
|
||||
|
||||
tx := &BaseTx{
|
||||
|
@ -304,10 +312,12 @@ func TestBaseTxSyntacticVerifyWrongChainID(t *testing.T) {
|
|||
c.RegisterType(&BaseTx{})
|
||||
c.RegisterType(&CreateAssetTx{})
|
||||
c.RegisterType(&OperationTx{})
|
||||
c.RegisterType(&ImportTx{})
|
||||
c.RegisterType(&ExportTx{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOutput{})
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{})
|
||||
c.RegisterType(&secp256k1fx.MintInput{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOperation{})
|
||||
c.RegisterType(&secp256k1fx.Credential{})
|
||||
|
||||
tx := &BaseTx{
|
||||
|
@ -354,10 +364,12 @@ func TestBaseTxSyntacticVerifyInvalidOutput(t *testing.T) {
|
|||
c.RegisterType(&BaseTx{})
|
||||
c.RegisterType(&CreateAssetTx{})
|
||||
c.RegisterType(&OperationTx{})
|
||||
c.RegisterType(&ImportTx{})
|
||||
c.RegisterType(&ExportTx{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOutput{})
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{})
|
||||
c.RegisterType(&secp256k1fx.MintInput{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOperation{})
|
||||
c.RegisterType(&secp256k1fx.Credential{})
|
||||
|
||||
tx := &BaseTx{
|
||||
|
@ -395,10 +407,12 @@ func TestBaseTxSyntacticVerifyUnsortedOutputs(t *testing.T) {
|
|||
c.RegisterType(&BaseTx{})
|
||||
c.RegisterType(&CreateAssetTx{})
|
||||
c.RegisterType(&OperationTx{})
|
||||
c.RegisterType(&ImportTx{})
|
||||
c.RegisterType(&ExportTx{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOutput{})
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{})
|
||||
c.RegisterType(&secp256k1fx.MintInput{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOperation{})
|
||||
c.RegisterType(&secp256k1fx.Credential{})
|
||||
|
||||
tx := &BaseTx{
|
||||
|
@ -459,10 +473,12 @@ func TestBaseTxSyntacticVerifyInvalidInput(t *testing.T) {
|
|||
c.RegisterType(&BaseTx{})
|
||||
c.RegisterType(&CreateAssetTx{})
|
||||
c.RegisterType(&OperationTx{})
|
||||
c.RegisterType(&ImportTx{})
|
||||
c.RegisterType(&ExportTx{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOutput{})
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{})
|
||||
c.RegisterType(&secp256k1fx.MintInput{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOperation{})
|
||||
c.RegisterType(&secp256k1fx.Credential{})
|
||||
|
||||
tx := &BaseTx{
|
||||
|
@ -492,10 +508,12 @@ func TestBaseTxSyntacticVerifyInputOverflow(t *testing.T) {
|
|||
c.RegisterType(&BaseTx{})
|
||||
c.RegisterType(&CreateAssetTx{})
|
||||
c.RegisterType(&OperationTx{})
|
||||
c.RegisterType(&ImportTx{})
|
||||
c.RegisterType(&ExportTx{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOutput{})
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{})
|
||||
c.RegisterType(&secp256k1fx.MintInput{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOperation{})
|
||||
c.RegisterType(&secp256k1fx.Credential{})
|
||||
|
||||
tx := &BaseTx{
|
||||
|
@ -562,10 +580,12 @@ func TestBaseTxSyntacticVerifyOutputOverflow(t *testing.T) {
|
|||
c.RegisterType(&BaseTx{})
|
||||
c.RegisterType(&CreateAssetTx{})
|
||||
c.RegisterType(&OperationTx{})
|
||||
c.RegisterType(&ImportTx{})
|
||||
c.RegisterType(&ExportTx{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOutput{})
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{})
|
||||
c.RegisterType(&secp256k1fx.MintInput{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOperation{})
|
||||
c.RegisterType(&secp256k1fx.Credential{})
|
||||
|
||||
tx := &BaseTx{
|
||||
|
@ -624,10 +644,12 @@ func TestBaseTxSyntacticVerifyInsufficientFunds(t *testing.T) {
|
|||
c.RegisterType(&BaseTx{})
|
||||
c.RegisterType(&CreateAssetTx{})
|
||||
c.RegisterType(&OperationTx{})
|
||||
c.RegisterType(&ImportTx{})
|
||||
c.RegisterType(&ExportTx{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOutput{})
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{})
|
||||
c.RegisterType(&secp256k1fx.MintInput{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOperation{})
|
||||
c.RegisterType(&secp256k1fx.Credential{})
|
||||
|
||||
tx := &BaseTx{
|
||||
|
@ -674,10 +696,12 @@ func TestBaseTxSyntacticVerifyUninitialized(t *testing.T) {
|
|||
c.RegisterType(&BaseTx{})
|
||||
c.RegisterType(&CreateAssetTx{})
|
||||
c.RegisterType(&OperationTx{})
|
||||
c.RegisterType(&ImportTx{})
|
||||
c.RegisterType(&ExportTx{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOutput{})
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{})
|
||||
c.RegisterType(&secp256k1fx.MintInput{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOperation{})
|
||||
c.RegisterType(&secp256k1fx.Credential{})
|
||||
|
||||
tx := &BaseTx{
|
||||
|
@ -972,14 +996,14 @@ func TestBaseTxSemanticVerifyUnauthorizedFx(t *testing.T) {
|
|||
genesisBytes,
|
||||
issuer,
|
||||
[]*common.Fx{
|
||||
&common.Fx{
|
||||
ID: ids.NewID([32]byte{1}),
|
||||
Fx: &testFx{},
|
||||
},
|
||||
&common.Fx{
|
||||
ID: ids.Empty,
|
||||
Fx: &secp256k1fx.Fx{},
|
||||
},
|
||||
&common.Fx{
|
||||
ID: ids.NewID([32]byte{1}),
|
||||
Fx: &testFx{},
|
||||
},
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
|
|
|
@ -34,7 +34,7 @@ func TestCreateAssetTxSerialization(t *testing.T) {
|
|||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
// output:
|
||||
0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xd4, 0x31, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x02, 0x51, 0x02, 0x5c, 0x61,
|
||||
|
@ -58,7 +58,7 @@ func TestCreateAssetTxSerialization(t *testing.T) {
|
|||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
// input:
|
||||
0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
|
||||
0x07, 0x5b, 0xcd, 0x15, 0x00, 0x00, 0x00, 0x02,
|
||||
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07,
|
||||
// name:
|
||||
|
@ -73,7 +73,7 @@ func TestCreateAssetTxSerialization(t *testing.T) {
|
|||
0x00, 0x00, 0x00, 0x01,
|
||||
// InitialStates[0]:
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xd4, 0x31, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x02, 0x51, 0x02, 0x5c, 0x61,
|
||||
|
@ -183,10 +183,12 @@ func TestCreateAssetTxSerialization(t *testing.T) {
|
|||
c.RegisterType(&BaseTx{})
|
||||
c.RegisterType(&CreateAssetTx{})
|
||||
c.RegisterType(&OperationTx{})
|
||||
c.RegisterType(&ImportTx{})
|
||||
c.RegisterType(&ExportTx{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOutput{})
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{})
|
||||
c.RegisterType(&secp256k1fx.MintInput{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOperation{})
|
||||
c.RegisterType(&secp256k1fx.Credential{})
|
||||
|
||||
b, err := c.Marshal(&tx.UnsignedTx)
|
||||
|
|
|
@ -17,7 +17,7 @@ import (
|
|||
type ExportTx struct {
|
||||
BaseTx `serialize:"true"`
|
||||
|
||||
Outs []*ava.TransferableOutput `serialize:"true"` // The outputs this transaction is sending to the other chain
|
||||
Outs []*ava.TransferableOutput `serialize:"true" json:"exportedOutputs"` // The outputs this transaction is sending to the other chain
|
||||
}
|
||||
|
||||
// SyntacticVerify that this transaction is well-formed.
|
||||
|
@ -97,7 +97,7 @@ func (t *ExportTx) SemanticVerify(vm *VM, uTx *UniqueTx, creds []verify.Verifiab
|
|||
return errIncompatibleFx
|
||||
}
|
||||
|
||||
if err := fx.VerifyTransfer(uTx, utxo.Out, in.In, cred); err != nil {
|
||||
if err := fx.VerifyTransfer(uTx, in.In, cred, utxo.Out); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ func TestExportTxSerialization(t *testing.T) {
|
|||
0x19, 0x39, 0x59, 0x79, 0x98, 0xb8, 0xd8, 0xf8,
|
||||
// input:
|
||||
// input ID:
|
||||
0x00, 0x00, 0x00, 0x08,
|
||||
0x00, 0x00, 0x00, 0x05,
|
||||
// amount:
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe8,
|
||||
// num sig indices:
|
||||
|
@ -93,10 +93,10 @@ func TestExportTxSerialization(t *testing.T) {
|
|||
c.RegisterType(&OperationTx{})
|
||||
c.RegisterType(&ImportTx{})
|
||||
c.RegisterType(&ExportTx{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOutput{})
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{})
|
||||
c.RegisterType(&secp256k1fx.MintInput{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOperation{})
|
||||
c.RegisterType(&secp256k1fx.Credential{})
|
||||
|
||||
b, err := c.Marshal(&tx.UnsignedTx)
|
||||
|
|
|
@ -5,6 +5,7 @@ package avm
|
|||
|
||||
import (
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/vms/components/verify"
|
||||
)
|
||||
|
||||
type parsedFx struct {
|
||||
|
@ -22,11 +23,18 @@ type Fx interface {
|
|||
// provided utxo with no restrictions on the destination. If the transaction
|
||||
// can't spend the output based on the input and credential, a non-nil error
|
||||
// should be returned.
|
||||
VerifyTransfer(tx, utxo, in, cred interface{}) error
|
||||
VerifyTransfer(tx, in, cred, utxo interface{}) error
|
||||
|
||||
// VerifyOperation verifies that the specified transaction can spend the
|
||||
// provided utxos conditioned on the result being restricted to the provided
|
||||
// outputs. If the transaction can't spend the output based on the input and
|
||||
// credential, a non-nil error should be returned.
|
||||
VerifyOperation(tx interface{}, utxos, ins, creds, outs []interface{}) error
|
||||
VerifyOperation(tx, op, cred interface{}, utxos []interface{}) error
|
||||
}
|
||||
|
||||
// FxOperation ...
|
||||
type FxOperation interface {
|
||||
verify.Verifiable
|
||||
|
||||
Outs() []verify.Verifiable
|
||||
}
|
||||
|
|
|
@ -9,6 +9,6 @@ type testFx struct {
|
|||
|
||||
func (fx *testFx) Initialize(_ interface{}) error { return fx.initialize }
|
||||
func (fx *testFx) VerifyTransfer(_, _, _, _ interface{}) error { return fx.verifyTransfer }
|
||||
func (fx *testFx) VerifyOperation(_ interface{}, _, _, _, _ []interface{}) error {
|
||||
func (fx *testFx) VerifyOperation(_, _, _ interface{}, _ []interface{}) error {
|
||||
return fx.verifyOperation
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
type ImportTx struct {
|
||||
BaseTx `serialize:"true"`
|
||||
|
||||
Ins []*ava.TransferableInput `serialize:"true"` // The inputs to this transaction
|
||||
Ins []*ava.TransferableInput `serialize:"true" json:"importedInputs"` // The inputs to this transaction
|
||||
}
|
||||
|
||||
// InputUTXOs track which UTXOs this transaction is consuming.
|
||||
|
@ -42,6 +42,9 @@ func (t *ImportTx) AssetIDs() ids.Set {
|
|||
return assets
|
||||
}
|
||||
|
||||
// NumCredentials returns the number of expected credentials
|
||||
func (t *ImportTx) NumCredentials() int { return t.BaseTx.NumCredentials() + len(t.Ins) }
|
||||
|
||||
var (
|
||||
errNoImportInputs = errors.New("no import inputs")
|
||||
)
|
||||
|
@ -106,7 +109,7 @@ func (t *ImportTx) SemanticVerify(vm *VM, uTx *UniqueTx, creds []verify.Verifiab
|
|||
|
||||
state := ava.NewPrefixedState(smDB, vm.codec)
|
||||
|
||||
offset := len(t.BaseTx.Ins)
|
||||
offset := t.BaseTx.NumCredentials()
|
||||
for i, in := range t.Ins {
|
||||
cred := creds[i+offset]
|
||||
|
||||
|
@ -134,7 +137,7 @@ func (t *ImportTx) SemanticVerify(vm *VM, uTx *UniqueTx, creds []verify.Verifiab
|
|||
return errIncompatibleFx
|
||||
}
|
||||
|
||||
if err := fx.VerifyTransfer(uTx, utxo.Out, in.In, cred); err != nil {
|
||||
if err := fx.VerifyTransfer(uTx, in.In, cred, utxo.Out); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ func TestImportTxSerialization(t *testing.T) {
|
|||
0x19, 0x39, 0x59, 0x79, 0x98, 0xb8, 0xd8, 0xf8,
|
||||
// input:
|
||||
// input ID:
|
||||
0x00, 0x00, 0x00, 0x08,
|
||||
0x00, 0x00, 0x00, 0x05,
|
||||
// amount:
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe8,
|
||||
// num sig indices:
|
||||
|
@ -95,10 +95,10 @@ func TestImportTxSerialization(t *testing.T) {
|
|||
c.RegisterType(&OperationTx{})
|
||||
c.RegisterType(&ImportTx{})
|
||||
c.RegisterType(&ExportTx{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOutput{})
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{})
|
||||
c.RegisterType(&secp256k1fx.MintInput{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOperation{})
|
||||
c.RegisterType(&secp256k1fx.Credential{})
|
||||
|
||||
b, err := c.Marshal(&tx.UnsignedTx)
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package avm
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"sort"
|
||||
|
||||
"github.com/ava-labs/gecko/utils"
|
||||
"github.com/ava-labs/gecko/vms/components/ava"
|
||||
"github.com/ava-labs/gecko/vms/components/verify"
|
||||
)
|
||||
|
||||
var (
|
||||
errNilOperableInput = errors.New("nil operable input is not valid")
|
||||
errNilOperableFxInput = errors.New("nil operable feature extension input is not valid")
|
||||
)
|
||||
|
||||
// OperableInput ...
|
||||
type OperableInput struct {
|
||||
ava.UTXOID `serialize:"true"`
|
||||
|
||||
In verify.Verifiable `serialize:"true" json:"input"`
|
||||
}
|
||||
|
||||
// Input returns the feature extension input that this Input is using.
|
||||
func (in *OperableInput) Input() verify.Verifiable { return in.In }
|
||||
|
||||
// Verify implements the verify.Verifiable interface
|
||||
func (in *OperableInput) Verify() error {
|
||||
switch {
|
||||
case in == nil:
|
||||
return errNilOperableInput
|
||||
case in.In == nil:
|
||||
return errNilOperableFxInput
|
||||
default:
|
||||
return verify.All(&in.UTXOID, in.In)
|
||||
}
|
||||
}
|
||||
|
||||
type innerSortOperableInputs []*OperableInput
|
||||
|
||||
func (ins innerSortOperableInputs) Less(i, j int) bool {
|
||||
iID, iIndex := ins[i].InputSource()
|
||||
jID, jIndex := ins[j].InputSource()
|
||||
|
||||
switch bytes.Compare(iID.Bytes(), jID.Bytes()) {
|
||||
case -1:
|
||||
return true
|
||||
case 0:
|
||||
return iIndex < jIndex
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
func (ins innerSortOperableInputs) Len() int { return len(ins) }
|
||||
func (ins innerSortOperableInputs) Swap(i, j int) { ins[j], ins[i] = ins[i], ins[j] }
|
||||
|
||||
func sortOperableInputs(ins []*OperableInput) { sort.Sort(innerSortOperableInputs(ins)) }
|
||||
func isSortedAndUniqueOperableInputs(ins []*OperableInput) bool {
|
||||
return utils.IsSortedAndUnique(innerSortOperableInputs(ins))
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package avm
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/vms/components/ava"
|
||||
)
|
||||
|
||||
func TestOperableInputVerifyNil(t *testing.T) {
|
||||
oi := (*OperableInput)(nil)
|
||||
if err := oi.Verify(); err == nil {
|
||||
t.Fatalf("Should have errored due to nil operable input")
|
||||
}
|
||||
}
|
||||
|
||||
func TestOperableInputVerifyNilFx(t *testing.T) {
|
||||
oi := &OperableInput{}
|
||||
if err := oi.Verify(); err == nil {
|
||||
t.Fatalf("Should have errored due to nil operable fx input")
|
||||
}
|
||||
}
|
||||
|
||||
func TestOperableInputVerify(t *testing.T) {
|
||||
oi := &OperableInput{
|
||||
UTXOID: ava.UTXOID{TxID: ids.Empty},
|
||||
In: &ava.TestVerifiable{},
|
||||
}
|
||||
if err := oi.Verify(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if oi.Input() != oi.In {
|
||||
t.Fatalf("Should have returned the fx input")
|
||||
}
|
||||
}
|
||||
|
||||
func TestOperableInputSorting(t *testing.T) {
|
||||
ins := []*OperableInput{
|
||||
&OperableInput{
|
||||
UTXOID: ava.UTXOID{
|
||||
TxID: ids.Empty,
|
||||
OutputIndex: 1,
|
||||
},
|
||||
In: &ava.TestVerifiable{},
|
||||
},
|
||||
&OperableInput{
|
||||
UTXOID: ava.UTXOID{
|
||||
TxID: ids.NewID([32]byte{1}),
|
||||
OutputIndex: 1,
|
||||
},
|
||||
In: &ava.TestVerifiable{},
|
||||
},
|
||||
&OperableInput{
|
||||
UTXOID: ava.UTXOID{
|
||||
TxID: ids.Empty,
|
||||
OutputIndex: 0,
|
||||
},
|
||||
In: &ava.TestVerifiable{},
|
||||
},
|
||||
&OperableInput{
|
||||
UTXOID: ava.UTXOID{
|
||||
TxID: ids.NewID([32]byte{1}),
|
||||
OutputIndex: 0,
|
||||
},
|
||||
In: &ava.TestVerifiable{},
|
||||
},
|
||||
}
|
||||
if isSortedAndUniqueOperableInputs(ins) {
|
||||
t.Fatalf("Shouldn't be sorted")
|
||||
}
|
||||
sortOperableInputs(ins)
|
||||
if !isSortedAndUniqueOperableInputs(ins) {
|
||||
t.Fatalf("Should be sorted")
|
||||
}
|
||||
if result := ins[0].OutputIndex; result != 0 {
|
||||
t.Fatalf("OutputIndex expected: %d ; result: %d", 0, result)
|
||||
}
|
||||
if result := ins[1].OutputIndex; result != 1 {
|
||||
t.Fatalf("OutputIndex expected: %d ; result: %d", 1, result)
|
||||
}
|
||||
if result := ins[2].OutputIndex; result != 0 {
|
||||
t.Fatalf("OutputIndex expected: %d ; result: %d", 0, result)
|
||||
}
|
||||
if result := ins[3].OutputIndex; result != 1 {
|
||||
t.Fatalf("OutputIndex expected: %d ; result: %d", 1, result)
|
||||
}
|
||||
if result := ins[0].TxID; !result.Equals(ids.Empty) {
|
||||
t.Fatalf("OutputIndex expected: %s ; result: %s", ids.Empty, result)
|
||||
}
|
||||
if result := ins[0].TxID; !result.Equals(ids.Empty) {
|
||||
t.Fatalf("OutputIndex expected: %s ; result: %s", ids.Empty, result)
|
||||
}
|
||||
ins = append(ins, &OperableInput{
|
||||
UTXOID: ava.UTXOID{
|
||||
TxID: ids.Empty,
|
||||
OutputIndex: 1,
|
||||
},
|
||||
In: &ava.TestVerifiable{},
|
||||
})
|
||||
if isSortedAndUniqueOperableInputs(ins) {
|
||||
t.Fatalf("Shouldn't be unique")
|
||||
}
|
||||
}
|
|
@ -15,16 +15,17 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
errNilOperation = errors.New("nil operation is not valid")
|
||||
errEmptyOperation = errors.New("empty operation is not valid")
|
||||
errNilOperation = errors.New("nil operation is not valid")
|
||||
errNilFxOperation = errors.New("nil fx operation is not valid")
|
||||
errNotSortedAndUniqueUTXOIDs = errors.New("utxo IDs not sorted and unique")
|
||||
)
|
||||
|
||||
// Operation ...
|
||||
type Operation struct {
|
||||
ava.Asset `serialize:"true"`
|
||||
|
||||
Ins []*OperableInput `serialize:"true" json:"inputs"`
|
||||
Outs []verify.Verifiable `serialize:"true" json:"outputs"`
|
||||
UTXOIDs []*ava.UTXOID `serialize:"true" json:"inputIDs"`
|
||||
Op FxOperation `serialize:"true" json:"operation"`
|
||||
}
|
||||
|
||||
// Verify implements the verify.Verifiable interface
|
||||
|
@ -32,29 +33,13 @@ func (op *Operation) Verify(c codec.Codec) error {
|
|||
switch {
|
||||
case op == nil:
|
||||
return errNilOperation
|
||||
case len(op.Ins) == 0 && len(op.Outs) == 0:
|
||||
return errEmptyOperation
|
||||
case op.Op == nil:
|
||||
return errNilFxOperation
|
||||
case !ava.IsSortedAndUniqueUTXOIDs(op.UTXOIDs):
|
||||
return errNotSortedAndUniqueUTXOIDs
|
||||
default:
|
||||
return verify.All(&op.Asset, op.Op)
|
||||
}
|
||||
|
||||
for _, in := range op.Ins {
|
||||
if err := in.Verify(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if !isSortedAndUniqueOperableInputs(op.Ins) {
|
||||
return errInputsNotSortedUnique
|
||||
}
|
||||
|
||||
for _, out := range op.Outs {
|
||||
if err := out.Verify(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if !isSortedVerifiables(op.Outs, c) {
|
||||
return errOutputsNotSorted
|
||||
}
|
||||
|
||||
return op.Asset.Verify()
|
||||
}
|
||||
|
||||
type innerSortOperation struct {
|
||||
|
|
|
@ -12,6 +12,14 @@ import (
|
|||
"github.com/ava-labs/gecko/vms/components/verify"
|
||||
)
|
||||
|
||||
type testOperable struct {
|
||||
ava.TestTransferable `serialize:"true"`
|
||||
|
||||
Outputs []verify.Verifiable `serialize:"true"`
|
||||
}
|
||||
|
||||
func (o *testOperable) Outs() []verify.Verifiable { return o.Outputs }
|
||||
|
||||
func TestOperationVerifyNil(t *testing.T) {
|
||||
c := codec.NewDefault()
|
||||
op := (*Operation)(nil)
|
||||
|
@ -30,58 +38,24 @@ func TestOperationVerifyEmpty(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestOperationVerifyInvalidInput(t *testing.T) {
|
||||
func TestOperationVerifyUTXOIDsNotSorted(t *testing.T) {
|
||||
c := codec.NewDefault()
|
||||
op := &Operation{
|
||||
Asset: ava.Asset{ID: ids.Empty},
|
||||
Ins: []*OperableInput{
|
||||
&OperableInput{},
|
||||
},
|
||||
}
|
||||
if err := op.Verify(c); err == nil {
|
||||
t.Fatalf("Should have errored due to an invalid input")
|
||||
}
|
||||
}
|
||||
|
||||
func TestOperationVerifyInputsNotSorted(t *testing.T) {
|
||||
c := codec.NewDefault()
|
||||
op := &Operation{
|
||||
Asset: ava.Asset{ID: ids.Empty},
|
||||
Ins: []*OperableInput{
|
||||
&OperableInput{
|
||||
UTXOID: ava.UTXOID{
|
||||
TxID: ids.Empty,
|
||||
OutputIndex: 1,
|
||||
},
|
||||
In: &ava.TestVerifiable{},
|
||||
UTXOIDs: []*ava.UTXOID{
|
||||
&ava.UTXOID{
|
||||
TxID: ids.Empty,
|
||||
OutputIndex: 1,
|
||||
},
|
||||
&OperableInput{
|
||||
UTXOID: ava.UTXOID{
|
||||
TxID: ids.Empty,
|
||||
OutputIndex: 0,
|
||||
},
|
||||
In: &ava.TestVerifiable{},
|
||||
&ava.UTXOID{
|
||||
TxID: ids.Empty,
|
||||
OutputIndex: 0,
|
||||
},
|
||||
},
|
||||
Op: &testOperable{},
|
||||
}
|
||||
if err := op.Verify(c); err == nil {
|
||||
t.Fatalf("Should have errored due to unsorted inputs")
|
||||
}
|
||||
}
|
||||
|
||||
func TestOperationVerifyOutputsNotSorted(t *testing.T) {
|
||||
c := codec.NewDefault()
|
||||
c.RegisterType(&ava.TestTransferable{})
|
||||
|
||||
op := &Operation{
|
||||
Asset: ava.Asset{ID: ids.Empty},
|
||||
Outs: []verify.Verifiable{
|
||||
&ava.TestTransferable{Val: 1},
|
||||
&ava.TestTransferable{Val: 0},
|
||||
},
|
||||
}
|
||||
if err := op.Verify(c); err == nil {
|
||||
t.Fatalf("Should have errored due to unsorted outputs")
|
||||
t.Fatalf("Should have errored due to unsorted utxoIDs")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,9 +63,13 @@ func TestOperationVerify(t *testing.T) {
|
|||
c := codec.NewDefault()
|
||||
op := &Operation{
|
||||
Asset: ava.Asset{ID: ids.Empty},
|
||||
Outs: []verify.Verifiable{
|
||||
&ava.TestVerifiable{},
|
||||
UTXOIDs: []*ava.UTXOID{
|
||||
&ava.UTXOID{
|
||||
TxID: ids.Empty,
|
||||
OutputIndex: 1,
|
||||
},
|
||||
},
|
||||
Op: &testOperable{},
|
||||
}
|
||||
if err := op.Verify(c); err != nil {
|
||||
t.Fatal(err)
|
||||
|
@ -100,32 +78,28 @@ func TestOperationVerify(t *testing.T) {
|
|||
|
||||
func TestOperationSorting(t *testing.T) {
|
||||
c := codec.NewDefault()
|
||||
c.RegisterType(&ava.TestVerifiable{})
|
||||
c.RegisterType(&testOperable{})
|
||||
|
||||
ops := []*Operation{
|
||||
&Operation{
|
||||
Asset: ava.Asset{ID: ids.Empty},
|
||||
Ins: []*OperableInput{
|
||||
&OperableInput{
|
||||
UTXOID: ava.UTXOID{
|
||||
TxID: ids.Empty,
|
||||
OutputIndex: 1,
|
||||
},
|
||||
In: &ava.TestVerifiable{},
|
||||
UTXOIDs: []*ava.UTXOID{
|
||||
&ava.UTXOID{
|
||||
TxID: ids.Empty,
|
||||
OutputIndex: 1,
|
||||
},
|
||||
},
|
||||
Op: &testOperable{},
|
||||
},
|
||||
&Operation{
|
||||
Asset: ava.Asset{ID: ids.Empty},
|
||||
Ins: []*OperableInput{
|
||||
&OperableInput{
|
||||
UTXOID: ava.UTXOID{
|
||||
TxID: ids.Empty,
|
||||
OutputIndex: 0,
|
||||
},
|
||||
In: &ava.TestVerifiable{},
|
||||
UTXOIDs: []*ava.UTXOID{
|
||||
&ava.UTXOID{
|
||||
TxID: ids.Empty,
|
||||
OutputIndex: 0,
|
||||
},
|
||||
},
|
||||
Op: &testOperable{},
|
||||
},
|
||||
}
|
||||
if isSortedAndUniqueOperations(ops, c) {
|
||||
|
@ -137,15 +111,13 @@ func TestOperationSorting(t *testing.T) {
|
|||
}
|
||||
ops = append(ops, &Operation{
|
||||
Asset: ava.Asset{ID: ids.Empty},
|
||||
Ins: []*OperableInput{
|
||||
&OperableInput{
|
||||
UTXOID: ava.UTXOID{
|
||||
TxID: ids.Empty,
|
||||
OutputIndex: 1,
|
||||
},
|
||||
In: &ava.TestVerifiable{},
|
||||
UTXOIDs: []*ava.UTXOID{
|
||||
&ava.UTXOID{
|
||||
TxID: ids.Empty,
|
||||
OutputIndex: 1,
|
||||
},
|
||||
},
|
||||
Op: &testOperable{},
|
||||
})
|
||||
if isSortedAndUniqueOperations(ops, c) {
|
||||
t.Fatalf("Shouldn't be unique")
|
||||
|
|
|
@ -34,9 +34,7 @@ func (t *OperationTx) Operations() []*Operation { return t.Ops }
|
|||
func (t *OperationTx) InputUTXOs() []*ava.UTXOID {
|
||||
utxos := t.BaseTx.InputUTXOs()
|
||||
for _, op := range t.Ops {
|
||||
for _, in := range op.Ins {
|
||||
utxos = append(utxos, &in.UTXOID)
|
||||
}
|
||||
utxos = append(utxos, op.UTXOIDs...)
|
||||
}
|
||||
return utxos
|
||||
}
|
||||
|
@ -50,6 +48,9 @@ func (t *OperationTx) AssetIDs() ids.Set {
|
|||
return assets
|
||||
}
|
||||
|
||||
// NumCredentials returns the number of expected credentials
|
||||
func (t *OperationTx) NumCredentials() int { return t.BaseTx.NumCredentials() + len(t.Ops) }
|
||||
|
||||
// UTXOs returns the UTXOs transaction is producing.
|
||||
func (t *OperationTx) UTXOs() []*ava.UTXO {
|
||||
txID := t.ID()
|
||||
|
@ -57,7 +58,7 @@ func (t *OperationTx) UTXOs() []*ava.UTXO {
|
|||
|
||||
for _, op := range t.Ops {
|
||||
asset := op.AssetID()
|
||||
for _, out := range op.Outs {
|
||||
for _, out := range op.Op.Outs() {
|
||||
utxos = append(utxos, &ava.UTXO{
|
||||
UTXOID: ava.UTXOID{
|
||||
TxID: txID,
|
||||
|
@ -94,8 +95,8 @@ func (t *OperationTx) SyntacticVerify(ctx *snow.Context, c codec.Codec, numFxs i
|
|||
if err := op.Verify(c); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, in := range op.Ins {
|
||||
inputID := in.InputID()
|
||||
for _, utxoID := range op.UTXOIDs {
|
||||
inputID := utxoID.InputID()
|
||||
if inputs.Contains(inputID) {
|
||||
return errDoubleSpend
|
||||
}
|
||||
|
@ -113,22 +114,14 @@ func (t *OperationTx) SemanticVerify(vm *VM, uTx *UniqueTx, creds []verify.Verif
|
|||
if err := t.BaseTx.SemanticVerify(vm, uTx, creds); err != nil {
|
||||
return err
|
||||
}
|
||||
offset := len(t.BaseTx.Ins)
|
||||
for _, op := range t.Ops {
|
||||
|
||||
offset := t.BaseTx.NumCredentials()
|
||||
for i, op := range t.Ops {
|
||||
opAssetID := op.AssetID()
|
||||
|
||||
utxos := []interface{}{}
|
||||
ins := []interface{}{}
|
||||
credIntfs := []interface{}{}
|
||||
outs := []interface{}{}
|
||||
|
||||
for i, in := range op.Ins {
|
||||
ins = append(ins, in.In)
|
||||
|
||||
cred := creds[i+offset]
|
||||
credIntfs = append(credIntfs, cred)
|
||||
|
||||
utxo, err := vm.getUTXO(&in.UTXOID)
|
||||
for _, utxoID := range op.UTXOIDs {
|
||||
utxo, err := vm.getUTXO(utxoID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -139,20 +132,8 @@ func (t *OperationTx) SemanticVerify(vm *VM, uTx *UniqueTx, creds []verify.Verif
|
|||
}
|
||||
utxos = append(utxos, utxo.Out)
|
||||
}
|
||||
offset += len(op.Ins)
|
||||
for _, out := range op.Outs {
|
||||
outs = append(outs, out)
|
||||
}
|
||||
|
||||
var fxObj interface{}
|
||||
switch {
|
||||
case len(ins) > 0:
|
||||
fxObj = ins[0]
|
||||
case len(outs) > 0:
|
||||
fxObj = outs[0]
|
||||
}
|
||||
|
||||
fxIndex, err := vm.getFx(fxObj)
|
||||
fxIndex, err := vm.getFx(op.Op)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -162,8 +143,7 @@ func (t *OperationTx) SemanticVerify(vm *VM, uTx *UniqueTx, creds []verify.Verif
|
|||
return errIncompatibleFx
|
||||
}
|
||||
|
||||
err = fx.VerifyOperation(uTx, utxos, ins, credIntfs, outs)
|
||||
if err != nil {
|
||||
if err := fx.VerifyOperation(uTx, op.Op, creds[offset+i], utxos); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -787,41 +787,35 @@ func (service *Service) CreateMintTx(r *http.Request, args *CreateMintTxArgs, re
|
|||
continue
|
||||
}
|
||||
|
||||
tx := Tx{
|
||||
UnsignedTx: &OperationTx{
|
||||
BaseTx: BaseTx{
|
||||
NetID: service.vm.ctx.NetworkID,
|
||||
BCID: service.vm.ctx.ChainID,
|
||||
},
|
||||
Ops: []*Operation{
|
||||
&Operation{
|
||||
Asset: ava.Asset{ID: assetID},
|
||||
Ins: []*OperableInput{
|
||||
&OperableInput{
|
||||
UTXOID: utxo.UTXOID,
|
||||
In: &secp256k1fx.MintInput{
|
||||
Input: secp256k1fx.Input{
|
||||
SigIndices: sigs,
|
||||
},
|
||||
},
|
||||
},
|
||||
tx := Tx{UnsignedTx: &OperationTx{
|
||||
BaseTx: BaseTx{
|
||||
NetID: service.vm.ctx.NetworkID,
|
||||
BCID: service.vm.ctx.ChainID,
|
||||
},
|
||||
Ops: []*Operation{
|
||||
&Operation{
|
||||
Asset: ava.Asset{ID: assetID},
|
||||
UTXOIDs: []*ava.UTXOID{
|
||||
&utxo.UTXOID,
|
||||
},
|
||||
Op: &secp256k1fx.MintOperation{
|
||||
MintInput: secp256k1fx.Input{
|
||||
SigIndices: sigs,
|
||||
},
|
||||
Outs: []verify.Verifiable{
|
||||
&secp256k1fx.MintOutput{
|
||||
OutputOwners: out.OutputOwners,
|
||||
},
|
||||
&secp256k1fx.TransferOutput{
|
||||
Amt: uint64(args.Amount),
|
||||
OutputOwners: secp256k1fx.OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{to},
|
||||
},
|
||||
MintOutput: secp256k1fx.MintOutput{
|
||||
OutputOwners: out.OutputOwners,
|
||||
},
|
||||
TransferOutput: secp256k1fx.TransferOutput{
|
||||
Amt: uint64(args.Amount),
|
||||
OutputOwners: secp256k1fx.OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{to},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}}
|
||||
|
||||
txBytes, err := service.vm.codec.Marshal(&tx)
|
||||
if err != nil {
|
||||
|
|
|
@ -136,7 +136,7 @@ func TestCreateFixedCapAsset(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if reply.AssetID.String() != "2PEdmaGjKsSd14xPHZkVjhDdxH1VBsCATW8gnmqfMYfp68EwU5" {
|
||||
if reply.AssetID.String() != "wWBk78PGAU4VkXhESr3jiYyMCEzzPPcnVYeEnNr9g4JuvYs2x" {
|
||||
t.Fatalf("Wrong assetID returned from CreateFixedCapAsset %s", reply.AssetID)
|
||||
}
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ func TestCreateVariableCapAsset(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if reply.AssetID.String() != "p58dzpQikQmKVp3QtXMrg4e9AcppDc7MgqjpQf18CiNrpr2ug" {
|
||||
if reply.AssetID.String() != "SscTvpQFCZPNiRXyueDc7LdHT9EstHiva3AK6kuTgHTMd7DsU" {
|
||||
t.Fatalf("Wrong assetID returned from CreateFixedCapAsset %s", reply.AssetID)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,10 +50,10 @@ func (*StaticService) BuildGenesis(_ *http.Request, args *BuildGenesisArgs, repl
|
|||
c.RegisterType(&OperationTx{})
|
||||
c.RegisterType(&ImportTx{})
|
||||
c.RegisterType(&ExportTx{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOutput{})
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{})
|
||||
c.RegisterType(&secp256k1fx.MintInput{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOperation{})
|
||||
c.RegisterType(&secp256k1fx.Credential{})
|
||||
|
||||
g := Genesis{}
|
||||
|
|
|
@ -5,8 +5,6 @@ package avm
|
|||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ava-labs/gecko/utils/formatting"
|
||||
)
|
||||
|
||||
func TestBuildGenesis(t *testing.T) {
|
||||
|
@ -79,89 +77,4 @@ func TestBuildGenesis(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
expected := formatting.CB58{Bytes: []byte{
|
||||
0x00, 0x00, 0x00, 0x03, 0x00, 0x06, 0x61, 0x73,
|
||||
0x73, 0x65, 0x74, 0x31, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0f, 0x6d, 0x79, 0x46, 0x69, 0x78, 0x65,
|
||||
0x64, 0x43, 0x61, 0x70, 0x41, 0x73, 0x73, 0x65,
|
||||
0x74, 0x00, 0x04, 0x4d, 0x46, 0x43, 0x41, 0x08,
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x50,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
|
||||
0x3f, 0x78, 0xe5, 0x10, 0xdf, 0x62, 0xbc, 0x48,
|
||||
0xb0, 0x82, 0x9e, 0xc0, 0x6d, 0x6a, 0x6b, 0x98,
|
||||
0x06, 0x2d, 0x69, 0x53, 0x00, 0x00, 0x00, 0x06,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x50,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
|
||||
0xc5, 0x49, 0x03, 0xde, 0x51, 0x77, 0xa1, 0x6f,
|
||||
0x78, 0x11, 0x77, 0x1e, 0xf2, 0xf4, 0x65, 0x9d,
|
||||
0x9e, 0x86, 0x46, 0x71, 0x00, 0x00, 0x00, 0x06,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0xa0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
|
||||
0x3f, 0x58, 0xfd, 0xa2, 0xe9, 0xea, 0x8d, 0x9e,
|
||||
0x4b, 0x18, 0x18, 0x32, 0xa0, 0x7b, 0x26, 0xda,
|
||||
0xe2, 0x86, 0xf2, 0xcb, 0x00, 0x00, 0x00, 0x06,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0xa0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
|
||||
0x64, 0x59, 0x38, 0xbb, 0x7a, 0xe2, 0x19, 0x32,
|
||||
0x70, 0xe6, 0xff, 0xef, 0x00, 0x9e, 0x36, 0x64,
|
||||
0xd1, 0x1e, 0x07, 0xc1, 0x00, 0x06, 0x61, 0x73,
|
||||
0x73, 0x65, 0x74, 0x32, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0d, 0x6d, 0x79, 0x56, 0x61, 0x72, 0x43,
|
||||
0x61, 0x70, 0x41, 0x73, 0x73, 0x65, 0x74, 0x00,
|
||||
0x04, 0x4d, 0x56, 0x43, 0x41, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x3f, 0x58,
|
||||
0xfd, 0xa2, 0xe9, 0xea, 0x8d, 0x9e, 0x4b, 0x18,
|
||||
0x18, 0x32, 0xa0, 0x7b, 0x26, 0xda, 0xe2, 0x86,
|
||||
0xf2, 0xcb, 0x64, 0x59, 0x38, 0xbb, 0x7a, 0xe2,
|
||||
0x19, 0x32, 0x70, 0xe6, 0xff, 0xef, 0x00, 0x9e,
|
||||
0x36, 0x64, 0xd1, 0x1e, 0x07, 0xc1, 0x00, 0x00,
|
||||
0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
|
||||
0x00, 0x02, 0x3f, 0x78, 0xe5, 0x10, 0xdf, 0x62,
|
||||
0xbc, 0x48, 0xb0, 0x82, 0x9e, 0xc0, 0x6d, 0x6a,
|
||||
0x6b, 0x98, 0x06, 0x2d, 0x69, 0x53, 0xc5, 0x49,
|
||||
0x03, 0xde, 0x51, 0x77, 0xa1, 0x6f, 0x78, 0x11,
|
||||
0x77, 0x1e, 0xf2, 0xf4, 0x65, 0x9d, 0x9e, 0x86,
|
||||
0x46, 0x71, 0x00, 0x06, 0x61, 0x73, 0x73, 0x65,
|
||||
0x74, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
|
||||
0x6d, 0x79, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x56,
|
||||
0x61, 0x72, 0x43, 0x61, 0x70, 0x41, 0x73, 0x73,
|
||||
0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x01, 0x64, 0x59, 0x38,
|
||||
0xbb, 0x7a, 0xe2, 0x19, 0x32, 0x70, 0xe6, 0xff,
|
||||
0xef, 0x00, 0x9e, 0x36, 0x64, 0xd1, 0x1e, 0x07,
|
||||
0xc1,
|
||||
}}
|
||||
|
||||
if result := reply.Bytes.String(); result != expected.String() {
|
||||
t.Fatalf("Create genesis returned:\n%s\nExpected:\n%s",
|
||||
formatting.DumpBytes{Bytes: reply.Bytes.Bytes},
|
||||
formatting.DumpBytes{Bytes: expected.Bytes},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ type UnsignedTx interface {
|
|||
Bytes() []byte
|
||||
|
||||
AssetIDs() ids.Set
|
||||
NumCredentials() int
|
||||
InputUTXOs() []*ava.UTXOID
|
||||
UTXOs() []*ava.UTXO
|
||||
|
||||
|
@ -65,8 +66,7 @@ func (t *Tx) SyntacticVerify(ctx *snow.Context, c codec.Codec, numFxs int) error
|
|||
}
|
||||
}
|
||||
|
||||
numInputs := len(t.InputUTXOs())
|
||||
if numInputs != len(t.Creds) {
|
||||
if numCreds := t.UnsignedTx.NumCredentials(); numCreds != len(t.Creds) {
|
||||
return errWrongNumberOfCredentials
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -27,6 +27,13 @@ func TestTxEmpty(t *testing.T) {
|
|||
c.RegisterType(&BaseTx{})
|
||||
c.RegisterType(&CreateAssetTx{})
|
||||
c.RegisterType(&OperationTx{})
|
||||
c.RegisterType(&ImportTx{})
|
||||
c.RegisterType(&ExportTx{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOutput{})
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{})
|
||||
c.RegisterType(&secp256k1fx.MintOperation{})
|
||||
c.RegisterType(&secp256k1fx.Credential{})
|
||||
|
||||
tx := &Tx{}
|
||||
if err := tx.SyntacticVerify(ctx, c, 1); err == nil {
|
||||
|
@ -39,10 +46,12 @@ func TestTxInvalidCredential(t *testing.T) {
|
|||
c.RegisterType(&BaseTx{})
|
||||
c.RegisterType(&CreateAssetTx{})
|
||||
c.RegisterType(&OperationTx{})
|
||||
c.RegisterType(&ImportTx{})
|
||||
c.RegisterType(&ExportTx{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOutput{})
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{})
|
||||
c.RegisterType(&secp256k1fx.MintInput{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOperation{})
|
||||
c.RegisterType(&secp256k1fx.Credential{})
|
||||
c.RegisterType(&ava.TestVerifiable{})
|
||||
|
||||
|
@ -85,10 +94,12 @@ func TestTxInvalidUnsignedTx(t *testing.T) {
|
|||
c.RegisterType(&BaseTx{})
|
||||
c.RegisterType(&CreateAssetTx{})
|
||||
c.RegisterType(&OperationTx{})
|
||||
c.RegisterType(&ImportTx{})
|
||||
c.RegisterType(&ExportTx{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOutput{})
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{})
|
||||
c.RegisterType(&secp256k1fx.MintInput{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOperation{})
|
||||
c.RegisterType(&secp256k1fx.Credential{})
|
||||
c.RegisterType(&ava.TestVerifiable{})
|
||||
|
||||
|
@ -151,19 +162,21 @@ func TestTxInvalidNumberOfCredentials(t *testing.T) {
|
|||
c.RegisterType(&BaseTx{})
|
||||
c.RegisterType(&CreateAssetTx{})
|
||||
c.RegisterType(&OperationTx{})
|
||||
c.RegisterType(&ImportTx{})
|
||||
c.RegisterType(&ExportTx{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOutput{})
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{})
|
||||
c.RegisterType(&secp256k1fx.MintInput{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOperation{})
|
||||
c.RegisterType(&secp256k1fx.Credential{})
|
||||
c.RegisterType(&ava.TestVerifiable{})
|
||||
|
||||
tx := &Tx{
|
||||
UnsignedTx: &OperationTx{
|
||||
BaseTx: BaseTx{
|
||||
NetID: networkID,
|
||||
BCID: chainID,
|
||||
Ins: []*ava.TransferableInput{&ava.TransferableInput{
|
||||
UnsignedTx: &BaseTx{
|
||||
NetID: networkID,
|
||||
BCID: chainID,
|
||||
Ins: []*ava.TransferableInput{
|
||||
&ava.TransferableInput{
|
||||
UTXOID: ava.UTXOID{TxID: ids.Empty, OutputIndex: 0},
|
||||
Asset: ava.Asset{ID: asset},
|
||||
In: &secp256k1fx.TransferInput{
|
||||
|
@ -174,18 +187,16 @@ func TestTxInvalidNumberOfCredentials(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
Ops: []*Operation{
|
||||
&Operation{
|
||||
Asset: ava.Asset{ID: asset},
|
||||
Ins: []*OperableInput{
|
||||
&OperableInput{
|
||||
UTXOID: ava.UTXOID{
|
||||
TxID: ids.Empty,
|
||||
OutputIndex: 1,
|
||||
},
|
||||
&ava.TransferableInput{
|
||||
UTXOID: ava.UTXOID{TxID: ids.Empty, OutputIndex: 1},
|
||||
Asset: ava.Asset{ID: asset},
|
||||
In: &secp256k1fx.TransferInput{
|
||||
Amt: 20 * units.KiloAva,
|
||||
Input: secp256k1fx.Input{
|
||||
SigIndices: []uint32{
|
||||
0,
|
||||
},
|
||||
In: &ava.TestVerifiable{},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -204,76 +215,3 @@ func TestTxInvalidNumberOfCredentials(t *testing.T) {
|
|||
t.Fatalf("Tx should have failed due to an invalid unsigned tx")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTxDocumentation(t *testing.T) {
|
||||
c := codec.NewDefault()
|
||||
c.RegisterType(&BaseTx{})
|
||||
c.RegisterType(&CreateAssetTx{})
|
||||
c.RegisterType(&OperationTx{})
|
||||
c.RegisterType(&secp256k1fx.MintOutput{})
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{})
|
||||
c.RegisterType(&secp256k1fx.MintInput{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.Credential{})
|
||||
|
||||
txBytes := []byte{
|
||||
// unsigned transaction:
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
|
||||
0xff, 0xff, 0xff, 0xff, 0xee, 0xee, 0xee, 0xee,
|
||||
0xdd, 0xdd, 0xdd, 0xdd, 0xcc, 0xcc, 0xcc, 0xcc,
|
||||
0xbb, 0xbb, 0xbb, 0xbb, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0x99, 0x99, 0x99, 0x99, 0x88, 0x88, 0x88, 0x88,
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x02, 0x03,
|
||||
0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
|
||||
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
|
||||
0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
|
||||
0x1c, 0x1d, 0x1e, 0x1f, 0x00, 0x00, 0x00, 0x04,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x31,
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
|
||||
0x51, 0x02, 0x5c, 0x61, 0xfb, 0xcf, 0xc0, 0x78,
|
||||
0xf6, 0x93, 0x34, 0xf8, 0x34, 0xbe, 0x6d, 0xd2,
|
||||
0x6d, 0x55, 0xa9, 0x55, 0xc3, 0x34, 0x41, 0x28,
|
||||
0xe0, 0x60, 0x12, 0x8e, 0xde, 0x35, 0x23, 0xa2,
|
||||
0x4a, 0x46, 0x1c, 0x89, 0x43, 0xab, 0x08, 0x59,
|
||||
0x00, 0x00, 0x00, 0x01, 0xf1, 0xe1, 0xd1, 0xc1,
|
||||
0xb1, 0xa1, 0x91, 0x81, 0x71, 0x61, 0x51, 0x41,
|
||||
0x31, 0x21, 0x11, 0x01, 0xf0, 0xe0, 0xd0, 0xc0,
|
||||
0xb0, 0xa0, 0x90, 0x80, 0x70, 0x60, 0x50, 0x40,
|
||||
0x30, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x05,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
|
||||
0x07, 0x5b, 0xcd, 0x15, 0x00, 0x00, 0x00, 0x02,
|
||||
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07,
|
||||
// number of credentials:
|
||||
0x00, 0x00, 0x00, 0x01,
|
||||
// credential[0]:
|
||||
0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1e, 0x1d, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
|
||||
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2e, 0x2d, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
||||
0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
0x00, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
|
||||
0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e,
|
||||
0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56,
|
||||
0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5e, 0x5d,
|
||||
0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
|
||||
0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6e, 0x6d,
|
||||
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
|
||||
0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e,
|
||||
0x7f, 0x00,
|
||||
}
|
||||
|
||||
tx := Tx{}
|
||||
err := c.Unmarshal(txBytes, &tx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
"github.com/ava-labs/gecko/snow/consensus/snowstorm"
|
||||
"github.com/ava-labs/gecko/snow/engine/common"
|
||||
"github.com/ava-labs/gecko/utils/formatting"
|
||||
"github.com/ava-labs/gecko/utils/logging"
|
||||
"github.com/ava-labs/gecko/utils/timer"
|
||||
"github.com/ava-labs/gecko/utils/wrappers"
|
||||
"github.com/ava-labs/gecko/vms/components/ava"
|
||||
|
@ -332,6 +333,9 @@ func (vm *VM) Clock() *timer.Clock { return &vm.clock }
|
|||
// Codec returns a reference to the internal codec of this VM
|
||||
func (vm *VM) Codec() codec.Codec { return vm.codec }
|
||||
|
||||
// Logger returns a reference to the internal logger of this VM
|
||||
func (vm *VM) Logger() logging.Logger { return vm.ctx.Log }
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
********************************** Timer API *********************************
|
||||
|
|
|
@ -54,10 +54,10 @@ func GetFirstTxFromGenesisTest(genesisBytes []byte, t *testing.T) *Tx {
|
|||
c.RegisterType(&OperationTx{})
|
||||
c.RegisterType(&ImportTx{})
|
||||
c.RegisterType(&ExportTx{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOutput{})
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{})
|
||||
c.RegisterType(&secp256k1fx.MintInput{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOperation{})
|
||||
c.RegisterType(&secp256k1fx.Credential{})
|
||||
|
||||
genesis := Genesis{}
|
||||
|
@ -192,7 +192,7 @@ func GenesisVM(t *testing.T) *VM {
|
|||
func TestTxSerialization(t *testing.T) {
|
||||
expected := []byte{
|
||||
// txID:
|
||||
0x00, 0x00, 0x00, 0x02,
|
||||
0x00, 0x00, 0x00, 0x01,
|
||||
// networkID:
|
||||
0x00, 0x00, 0xa8, 0x66,
|
||||
// chainID:
|
||||
|
@ -209,7 +209,7 @@ func TestTxSerialization(t *testing.T) {
|
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// fxID:
|
||||
0x00, 0x00, 0x00, 0x06,
|
||||
0x00, 0x00, 0x00, 0x07,
|
||||
// secp256k1 Transferable Output:
|
||||
// amount:
|
||||
0x00, 0x00, 0x12, 0x30, 0x9c, 0xe5, 0x40, 0x00,
|
||||
|
@ -230,7 +230,7 @@ func TestTxSerialization(t *testing.T) {
|
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// fxID:
|
||||
0x00, 0x00, 0x00, 0x06,
|
||||
0x00, 0x00, 0x00, 0x07,
|
||||
// secp256k1 Transferable Output:
|
||||
// amount:
|
||||
0x00, 0x00, 0x12, 0x30, 0x9c, 0xe5, 0x40, 0x00,
|
||||
|
@ -251,7 +251,7 @@ func TestTxSerialization(t *testing.T) {
|
|||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// fxID:
|
||||
0x00, 0x00, 0x00, 0x06,
|
||||
0x00, 0x00, 0x00, 0x07,
|
||||
// secp256k1 Transferable Output:
|
||||
// amount:
|
||||
0x00, 0x00, 0x12, 0x30, 0x9c, 0xe5, 0x40, 0x00,
|
||||
|
@ -267,20 +267,24 @@ func TestTxSerialization(t *testing.T) {
|
|||
0x92, 0xf0, 0xee, 0x31,
|
||||
// number of inputs:
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
// number of operations:
|
||||
// name length:
|
||||
0x00, 0x04,
|
||||
// name:
|
||||
'n', 'a', 'm', 'e',
|
||||
// symbol length:
|
||||
0x00, 0x04,
|
||||
// symbol:
|
||||
's', 'y', 'm', 'b',
|
||||
// denomination
|
||||
0x00,
|
||||
// number of initial states:
|
||||
0x00, 0x00, 0x00, 0x01,
|
||||
// operation[0]:
|
||||
// assetID:
|
||||
0x01, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// number of inputs:
|
||||
// fx index:
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
// number of outputs:
|
||||
0x00, 0x00, 0x00, 0x01,
|
||||
// fxID:
|
||||
0x00, 0x00, 0x00, 0x05,
|
||||
0x00, 0x00, 0x00, 0x06,
|
||||
// secp256k1 Mint Output:
|
||||
// threshold:
|
||||
0x00, 0x00, 0x00, 0x01,
|
||||
|
@ -294,14 +298,17 @@ func TestTxSerialization(t *testing.T) {
|
|||
0x00, 0x00, 0x00, 0x00,
|
||||
}
|
||||
|
||||
unsignedTx := &OperationTx{
|
||||
unsignedTx := &CreateAssetTx{
|
||||
BaseTx: BaseTx{
|
||||
NetID: networkID,
|
||||
BCID: chainID,
|
||||
},
|
||||
Ops: []*Operation{
|
||||
&Operation{
|
||||
Asset: ava.Asset{ID: asset},
|
||||
Name: "name",
|
||||
Symbol: "symb",
|
||||
Denomination: 0,
|
||||
States: []*InitialState{
|
||||
&InitialState{
|
||||
FxID: 0,
|
||||
Outs: []verify.Verifiable{
|
||||
&secp256k1fx.MintOutput{
|
||||
OutputOwners: secp256k1fx.OutputOwners{
|
||||
|
@ -335,10 +342,10 @@ func TestTxSerialization(t *testing.T) {
|
|||
c.RegisterType(&OperationTx{})
|
||||
c.RegisterType(&ImportTx{})
|
||||
c.RegisterType(&ExportTx{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOutput{})
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{})
|
||||
c.RegisterType(&secp256k1fx.MintInput{})
|
||||
c.RegisterType(&secp256k1fx.TransferInput{})
|
||||
c.RegisterType(&secp256k1fx.MintOperation{})
|
||||
c.RegisterType(&secp256k1fx.Credential{})
|
||||
|
||||
b, err := c.Marshal(tx)
|
||||
|
|
|
@ -4,9 +4,12 @@
|
|||
package ava
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"sort"
|
||||
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -52,3 +55,29 @@ func (utxo *UTXOID) Verify() error {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
type innerSortUTXOIDs []*UTXOID
|
||||
|
||||
func (utxos innerSortUTXOIDs) Less(i, j int) bool {
|
||||
iID, iIndex := utxos[i].InputSource()
|
||||
jID, jIndex := utxos[j].InputSource()
|
||||
|
||||
switch bytes.Compare(iID.Bytes(), jID.Bytes()) {
|
||||
case -1:
|
||||
return true
|
||||
case 0:
|
||||
return iIndex < jIndex
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
func (utxos innerSortUTXOIDs) Len() int { return len(utxos) }
|
||||
func (utxos innerSortUTXOIDs) Swap(i, j int) { utxos[j], utxos[i] = utxos[i], utxos[j] }
|
||||
|
||||
// SortUTXOIDs ...
|
||||
func SortUTXOIDs(utxos []*UTXOID) { sort.Sort(innerSortUTXOIDs(utxos)) }
|
||||
|
||||
// IsSortedAndUniqueUTXOIDs ...
|
||||
func IsSortedAndUniqueUTXOIDs(utxos []*UTXOID) bool {
|
||||
return utils.IsSortedAndUnique(innerSortUTXOIDs(utxos))
|
||||
}
|
||||
|
|
|
@ -194,7 +194,7 @@ func (tx *ImportTx) SemanticVerify(db database.Database) error {
|
|||
return errAssetIDMismatch
|
||||
}
|
||||
|
||||
if err := tx.vm.fx.VerifyTransfer(tx, utxo.Out, in.In, cred); err != nil {
|
||||
if err := tx.vm.fx.VerifyTransfer(tx, in.In, cred, utxo.Out); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"github.com/ava-labs/gecko/snow/engine/common"
|
||||
"github.com/ava-labs/gecko/snow/validators"
|
||||
"github.com/ava-labs/gecko/utils/crypto"
|
||||
"github.com/ava-labs/gecko/utils/logging"
|
||||
"github.com/ava-labs/gecko/utils/math"
|
||||
"github.com/ava-labs/gecko/utils/timer"
|
||||
"github.com/ava-labs/gecko/utils/units"
|
||||
|
@ -112,10 +113,10 @@ func init() {
|
|||
Codec.RegisterType(&StandardBlock{}),
|
||||
Codec.RegisterType(&AtomicBlock{}),
|
||||
|
||||
Codec.RegisterType(&secp256k1fx.TransferInput{}),
|
||||
Codec.RegisterType(&secp256k1fx.MintOutput{}),
|
||||
Codec.RegisterType(&secp256k1fx.TransferOutput{}),
|
||||
Codec.RegisterType(&secp256k1fx.MintInput{}),
|
||||
Codec.RegisterType(&secp256k1fx.TransferInput{}),
|
||||
Codec.RegisterType(&secp256k1fx.MintOperation{}),
|
||||
Codec.RegisterType(&secp256k1fx.Credential{}),
|
||||
|
||||
Codec.RegisterType(&UnsignedAddDefaultSubnetValidatorTx{}),
|
||||
|
@ -742,6 +743,9 @@ func (vm *VM) Codec() codec.Codec { return vm.codec }
|
|||
// Clock ...
|
||||
func (vm *VM) Clock() *timer.Clock { return &vm.clock }
|
||||
|
||||
// Logger ...
|
||||
func (vm *VM) Logger() logging.Logger { return vm.Ctx.Log }
|
||||
|
||||
// GetAtomicUTXOs returns the utxos that at least one of the provided addresses is
|
||||
// referenced in.
|
||||
func (vm *VM) GetAtomicUTXOs(addrs ids.Set) ([]*ava.UTXO, error) {
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package secp256k1fx
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFactory(t *testing.T) {
|
||||
factory := Factory{}
|
||||
if fx := factory.New(); fx == nil {
|
||||
t.Fatalf("Factory.New returned nil")
|
||||
}
|
||||
}
|
|
@ -8,23 +8,22 @@ import (
|
|||
|
||||
"github.com/ava-labs/gecko/utils/crypto"
|
||||
"github.com/ava-labs/gecko/utils/hashing"
|
||||
"github.com/ava-labs/gecko/utils/wrappers"
|
||||
"github.com/ava-labs/gecko/vms/components/verify"
|
||||
)
|
||||
|
||||
var (
|
||||
errWrongVMType = errors.New("wrong vm type")
|
||||
errWrongTxType = errors.New("wrong tx type")
|
||||
errWrongOpType = errors.New("wrong operation type")
|
||||
errWrongUTXOType = errors.New("wrong utxo type")
|
||||
errWrongOutputType = errors.New("wrong output type")
|
||||
errWrongInputType = errors.New("wrong input type")
|
||||
errWrongCredentialType = errors.New("wrong credential type")
|
||||
|
||||
errWrongNumberOfOutputs = errors.New("wrong number of outputs for an operation")
|
||||
errWrongNumberOfInputs = errors.New("wrong number of inputs for an operation")
|
||||
errWrongNumberOfCredentials = errors.New("wrong number of credentials for an operation")
|
||||
|
||||
errWrongMintCreated = errors.New("wrong mint output created from the operation")
|
||||
errWrongNumberOfUTXOs = errors.New("wrong number of utxos for the operation")
|
||||
|
||||
errWrongMintCreated = errors.New("wrong mint output created from the operation")
|
||||
errWrongAmounts = errors.New("input is consuming a different amount than expected")
|
||||
errTimelocked = errors.New("output is time locked")
|
||||
errTooManySigners = errors.New("input has more signers than expected")
|
||||
|
@ -33,93 +32,85 @@ var (
|
|||
errWrongSigner = errors.New("credential does not produce expected signer")
|
||||
)
|
||||
|
||||
// Fx ...
|
||||
// Fx describes the secp256k1 feature extension
|
||||
type Fx struct {
|
||||
vm VM
|
||||
secpFactory crypto.FactorySECP256K1R
|
||||
VM VM
|
||||
SECPFactory crypto.FactorySECP256K1R
|
||||
}
|
||||
|
||||
// Initialize ...
|
||||
func (fx *Fx) Initialize(vmIntf interface{}) error {
|
||||
if err := fx.InitializeVM(vmIntf); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log := fx.VM.Logger()
|
||||
log.Debug("Initializing secp561k1 fx")
|
||||
|
||||
c := fx.VM.Codec()
|
||||
errs := wrappers.Errs{}
|
||||
errs.Add(
|
||||
c.RegisterType(&TransferInput{}),
|
||||
c.RegisterType(&MintOutput{}),
|
||||
c.RegisterType(&TransferOutput{}),
|
||||
c.RegisterType(&MintOperation{}),
|
||||
c.RegisterType(&Credential{}),
|
||||
)
|
||||
return errs.Err
|
||||
}
|
||||
|
||||
// InitializeVM ...
|
||||
func (fx *Fx) InitializeVM(vmIntf interface{}) error {
|
||||
vm, ok := vmIntf.(VM)
|
||||
if !ok {
|
||||
return errWrongVMType
|
||||
}
|
||||
|
||||
c := vm.Codec()
|
||||
c.RegisterType(&MintOutput{})
|
||||
c.RegisterType(&TransferOutput{})
|
||||
c.RegisterType(&MintInput{})
|
||||
c.RegisterType(&TransferInput{})
|
||||
c.RegisterType(&Credential{})
|
||||
|
||||
fx.vm = vm
|
||||
fx.VM = vm
|
||||
return nil
|
||||
}
|
||||
|
||||
// VerifyOperation ...
|
||||
func (fx *Fx) VerifyOperation(txIntf interface{}, utxosIntf, insIntf, credsIntf, outsIntf []interface{}) error {
|
||||
func (fx *Fx) VerifyOperation(txIntf, opIntf, credIntf interface{}, utxosIntf []interface{}) error {
|
||||
tx, ok := txIntf.(Tx)
|
||||
if !ok {
|
||||
return errWrongTxType
|
||||
}
|
||||
|
||||
if len(outsIntf) != 2 {
|
||||
return errWrongNumberOfOutputs
|
||||
}
|
||||
if len(utxosIntf) != 1 || len(insIntf) != 1 {
|
||||
return errWrongNumberOfInputs
|
||||
}
|
||||
if len(credsIntf) != 1 {
|
||||
return errWrongNumberOfCredentials
|
||||
}
|
||||
|
||||
utxo, ok := utxosIntf[0].(*MintOutput)
|
||||
op, ok := opIntf.(*MintOperation)
|
||||
if !ok {
|
||||
return errWrongUTXOType
|
||||
return errWrongOpType
|
||||
}
|
||||
in, ok := insIntf[0].(*MintInput)
|
||||
if !ok {
|
||||
return errWrongInputType
|
||||
}
|
||||
cred, ok := credsIntf[0].(*Credential)
|
||||
cred, ok := credIntf.(*Credential)
|
||||
if !ok {
|
||||
return errWrongCredentialType
|
||||
}
|
||||
newMint, ok := outsIntf[0].(*MintOutput)
|
||||
if !ok {
|
||||
return errWrongOutputType
|
||||
if len(utxosIntf) != 1 {
|
||||
return errWrongNumberOfUTXOs
|
||||
}
|
||||
newOutput, ok := outsIntf[1].(*TransferOutput)
|
||||
out, ok := utxosIntf[0].(*MintOutput)
|
||||
if !ok {
|
||||
return errWrongOutputType
|
||||
return errWrongUTXOType
|
||||
}
|
||||
|
||||
return fx.verifyOperation(tx, utxo, in, cred, newMint, newOutput)
|
||||
return fx.verifyOperation(tx, op, cred, out)
|
||||
}
|
||||
|
||||
func (fx *Fx) verifyOperation(tx Tx, utxo *MintOutput, in *MintInput, cred *Credential, newMint *MintOutput, newOutput *TransferOutput) error {
|
||||
if err := verify.All(utxo, in, cred, newMint, newOutput); err != nil {
|
||||
func (fx *Fx) verifyOperation(tx Tx, op *MintOperation, cred *Credential, utxo *MintOutput) error {
|
||||
if err := verify.All(op, cred, utxo); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !utxo.Equals(&newMint.OutputOwners) {
|
||||
if !utxo.Equals(&op.MintOutput.OutputOwners) {
|
||||
return errWrongMintCreated
|
||||
}
|
||||
|
||||
return fx.verifyCredentials(tx, &utxo.OutputOwners, &in.Input, cred)
|
||||
return fx.VerifyCredentials(tx, &op.MintInput, cred, &utxo.OutputOwners)
|
||||
}
|
||||
|
||||
// VerifyTransfer ...
|
||||
func (fx *Fx) VerifyTransfer(txIntf, utxoIntf, inIntf, credIntf interface{}) error {
|
||||
func (fx *Fx) VerifyTransfer(txIntf, inIntf, credIntf, utxoIntf interface{}) error {
|
||||
tx, ok := txIntf.(Tx)
|
||||
if !ok {
|
||||
return errWrongTxType
|
||||
}
|
||||
utxo, ok := utxoIntf.(*TransferOutput)
|
||||
if !ok {
|
||||
return errWrongUTXOType
|
||||
}
|
||||
in, ok := inIntf.(*TransferInput)
|
||||
if !ok {
|
||||
return errWrongInputType
|
||||
|
@ -128,15 +119,20 @@ func (fx *Fx) VerifyTransfer(txIntf, utxoIntf, inIntf, credIntf interface{}) err
|
|||
if !ok {
|
||||
return errWrongCredentialType
|
||||
}
|
||||
return fx.verifyTransfer(tx, utxo, in, cred)
|
||||
out, ok := utxoIntf.(*TransferOutput)
|
||||
if !ok {
|
||||
return errWrongUTXOType
|
||||
}
|
||||
return fx.VerifySpend(tx, in, cred, out)
|
||||
}
|
||||
|
||||
func (fx *Fx) verifyTransfer(tx Tx, utxo *TransferOutput, in *TransferInput, cred *Credential) error {
|
||||
// VerifySpend ensures that the utxo can be sent to any address
|
||||
func (fx *Fx) VerifySpend(tx Tx, in *TransferInput, cred *Credential, utxo *TransferOutput) error {
|
||||
if err := verify.All(utxo, in, cred); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
clock := fx.vm.Clock()
|
||||
clock := fx.VM.Clock()
|
||||
switch {
|
||||
case utxo.Amt != in.Amt:
|
||||
return errWrongAmounts
|
||||
|
@ -144,10 +140,12 @@ func (fx *Fx) verifyTransfer(tx Tx, utxo *TransferOutput, in *TransferInput, cre
|
|||
return errTimelocked
|
||||
}
|
||||
|
||||
return fx.verifyCredentials(tx, &utxo.OutputOwners, &in.Input, cred)
|
||||
return fx.VerifyCredentials(tx, &in.Input, cred, &utxo.OutputOwners)
|
||||
}
|
||||
|
||||
func (fx *Fx) verifyCredentials(tx Tx, out *OutputOwners, in *Input, cred *Credential) error {
|
||||
// VerifyCredentials ensures that the output can be spent by the input with the
|
||||
// credential. A nil return values means the output can be spent.
|
||||
func (fx *Fx) VerifyCredentials(tx Tx, in *Input, cred *Credential, out *OutputOwners) error {
|
||||
numSigs := len(in.SigIndices)
|
||||
switch {
|
||||
case out.Threshold < uint32(numSigs):
|
||||
|
@ -164,7 +162,7 @@ func (fx *Fx) verifyCredentials(tx Tx, out *OutputOwners, in *Input, cred *Crede
|
|||
for i, index := range in.SigIndices {
|
||||
sig := cred.Sigs[i]
|
||||
|
||||
pk, err := fx.secpFactory.RecoverHashPublicKey(txHash, sig[:])
|
||||
pk, err := fx.SECPFactory.RecoverHashPublicKey(txHash, sig[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/utils/crypto"
|
||||
"github.com/ava-labs/gecko/utils/hashing"
|
||||
"github.com/ava-labs/gecko/utils/logging"
|
||||
"github.com/ava-labs/gecko/utils/timer"
|
||||
"github.com/ava-labs/gecko/vms/components/codec"
|
||||
)
|
||||
|
@ -40,6 +41,8 @@ func (vm *testVM) Codec() codec.Codec { return codec.NewDefault() }
|
|||
|
||||
func (vm *testVM) Clock() *timer.Clock { return &vm.clock }
|
||||
|
||||
func (vm *testVM) Logger() logging.Logger { return logging.NoLog{} }
|
||||
|
||||
type testCodec struct{}
|
||||
|
||||
func (c *testCodec) RegisterStruct(interface{}) {}
|
||||
|
@ -98,8 +101,7 @@ func TestFxVerifyTransfer(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
err := fx.VerifyTransfer(tx, out, in, cred)
|
||||
if err != nil {
|
||||
if err := fx.VerifyTransfer(tx, in, cred, out); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
@ -134,8 +136,7 @@ func TestFxVerifyTransferNilTx(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
err := fx.VerifyTransfer(nil, out, in, cred)
|
||||
if err == nil {
|
||||
if err := fx.VerifyTransfer(nil, in, cred, out); err == nil {
|
||||
t.Fatalf("Should have failed verification due to a nil tx")
|
||||
}
|
||||
}
|
||||
|
@ -163,8 +164,7 @@ func TestFxVerifyTransferNilOutput(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
err := fx.VerifyTransfer(tx, nil, in, cred)
|
||||
if err == nil {
|
||||
if err := fx.VerifyTransfer(tx, in, cred, nil); err == nil {
|
||||
t.Fatalf("Should have failed verification due to a nil output")
|
||||
}
|
||||
}
|
||||
|
@ -196,8 +196,7 @@ func TestFxVerifyTransferNilInput(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
err := fx.VerifyTransfer(tx, out, nil, cred)
|
||||
if err == nil {
|
||||
if err := fx.VerifyTransfer(tx, nil, cred, out); err == nil {
|
||||
t.Fatalf("Should have failed verification due to a nil input")
|
||||
}
|
||||
}
|
||||
|
@ -230,8 +229,7 @@ func TestFxVerifyTransferNilCredential(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
err := fx.VerifyTransfer(tx, out, in, nil)
|
||||
if err == nil {
|
||||
if err := fx.VerifyTransfer(tx, in, nil, out); err == nil {
|
||||
t.Fatalf("Should have failed verification due to a nil credential")
|
||||
}
|
||||
}
|
||||
|
@ -269,8 +267,7 @@ func TestFxVerifyTransferInvalidOutput(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
err := fx.VerifyTransfer(tx, out, in, cred)
|
||||
if err == nil {
|
||||
if err := fx.VerifyTransfer(tx, in, cred, out); err == nil {
|
||||
t.Fatalf("Should have errored due to an invalid output")
|
||||
}
|
||||
}
|
||||
|
@ -308,8 +305,7 @@ func TestFxVerifyTransferWrongAmounts(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
err := fx.VerifyTransfer(tx, out, in, cred)
|
||||
if err == nil {
|
||||
if err := fx.VerifyTransfer(tx, in, cred, out); err == nil {
|
||||
t.Fatalf("Should have errored due to different amounts")
|
||||
}
|
||||
}
|
||||
|
@ -347,8 +343,7 @@ func TestFxVerifyTransferTimelocked(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
err := fx.VerifyTransfer(tx, out, in, cred)
|
||||
if err == nil {
|
||||
if err := fx.VerifyTransfer(tx, in, cred, out); err == nil {
|
||||
t.Fatalf("Should have errored due to a timelocked output")
|
||||
}
|
||||
}
|
||||
|
@ -387,8 +382,7 @@ func TestFxVerifyTransferTooManySigners(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
err := fx.VerifyTransfer(tx, out, in, cred)
|
||||
if err == nil {
|
||||
if err := fx.VerifyTransfer(tx, in, cred, out); err == nil {
|
||||
t.Fatalf("Should have errored due to too many signers")
|
||||
}
|
||||
}
|
||||
|
@ -424,8 +418,7 @@ func TestFxVerifyTransferTooFewSigners(t *testing.T) {
|
|||
Sigs: [][crypto.SECP256K1RSigLen]byte{},
|
||||
}
|
||||
|
||||
err := fx.VerifyTransfer(tx, out, in, cred)
|
||||
if err == nil {
|
||||
if err := fx.VerifyTransfer(tx, in, cred, out); err == nil {
|
||||
t.Fatalf("Should have errored due to too few signers")
|
||||
}
|
||||
}
|
||||
|
@ -464,8 +457,7 @@ func TestFxVerifyTransferMismatchedSigners(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
err := fx.VerifyTransfer(tx, out, in, cred)
|
||||
if err == nil {
|
||||
if err := fx.VerifyTransfer(tx, in, cred, out); err == nil {
|
||||
t.Fatalf("Should have errored due to too mismatched signers")
|
||||
}
|
||||
}
|
||||
|
@ -503,8 +495,7 @@ func TestFxVerifyTransferInvalidSignature(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
err := fx.VerifyTransfer(tx, out, in, cred)
|
||||
if err == nil {
|
||||
if err := fx.VerifyTransfer(tx, in, cred, out); err == nil {
|
||||
t.Fatalf("Should have errored due to an invalid signature")
|
||||
}
|
||||
}
|
||||
|
@ -542,8 +533,7 @@ func TestFxVerifyTransferWrongSigner(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
err := fx.VerifyTransfer(tx, out, in, cred)
|
||||
if err == nil {
|
||||
if err := fx.VerifyTransfer(tx, in, cred, out); err == nil {
|
||||
t.Fatalf("Should have errored due to a wrong signer")
|
||||
}
|
||||
}
|
||||
|
@ -567,40 +557,37 @@ func TestFxVerifyOperation(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
in := &MintInput{
|
||||
Input: Input{
|
||||
op := &MintOperation{
|
||||
MintInput: Input{
|
||||
SigIndices: []uint32{0},
|
||||
},
|
||||
MintOutput: MintOutput{
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
},
|
||||
TransferOutput: TransferOutput{
|
||||
Amt: 1,
|
||||
Locktime: 0,
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
cred := &Credential{
|
||||
Sigs: [][crypto.SECP256K1RSigLen]byte{
|
||||
sigBytes,
|
||||
},
|
||||
}
|
||||
mintOutput := &MintOutput{
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
}
|
||||
transferOutput := &TransferOutput{
|
||||
Amt: 1,
|
||||
Locktime: 0,
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
utxos := []interface{}{utxo}
|
||||
ins := []interface{}{in}
|
||||
creds := []interface{}{cred}
|
||||
outs := []interface{}{mintOutput, transferOutput}
|
||||
err := fx.VerifyOperation(tx, utxos, ins, creds, outs)
|
||||
err := fx.VerifyOperation(tx, op, cred, utxos)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -622,94 +609,43 @@ func TestFxVerifyOperationUnknownTx(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
in := &MintInput{
|
||||
Input: Input{
|
||||
op := &MintOperation{
|
||||
MintInput: Input{
|
||||
SigIndices: []uint32{0},
|
||||
},
|
||||
MintOutput: MintOutput{
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
},
|
||||
TransferOutput: TransferOutput{
|
||||
Amt: 1,
|
||||
Locktime: 0,
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
cred := &Credential{
|
||||
Sigs: [][crypto.SECP256K1RSigLen]byte{
|
||||
sigBytes,
|
||||
},
|
||||
}
|
||||
mintOutput := &MintOutput{
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
}
|
||||
transferOutput := &TransferOutput{
|
||||
Amt: 1,
|
||||
Locktime: 0,
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
utxos := []interface{}{utxo}
|
||||
ins := []interface{}{in}
|
||||
creds := []interface{}{cred}
|
||||
outs := []interface{}{mintOutput, transferOutput}
|
||||
err := fx.VerifyOperation(nil, utxos, ins, creds, outs)
|
||||
err := fx.VerifyOperation(nil, op, cred, utxos)
|
||||
if err == nil {
|
||||
t.Fatalf("Should have errored due to an invalid tx type")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFxVerifyOperationWrongNumberOfOutputs(t *testing.T) {
|
||||
vm := testVM{}
|
||||
date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
|
||||
vm.clock.Set(date)
|
||||
fx := Fx{}
|
||||
if err := fx.Initialize(&vm); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tx := &testTx{
|
||||
bytes: txBytes,
|
||||
}
|
||||
utxo := &MintOutput{
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
}
|
||||
in := &MintInput{
|
||||
Input: Input{
|
||||
SigIndices: []uint32{0},
|
||||
},
|
||||
}
|
||||
cred := &Credential{
|
||||
Sigs: [][crypto.SECP256K1RSigLen]byte{
|
||||
sigBytes,
|
||||
},
|
||||
}
|
||||
mintOutput := &MintOutput{
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
utxos := []interface{}{utxo}
|
||||
ins := []interface{}{in}
|
||||
creds := []interface{}{cred}
|
||||
outs := []interface{}{mintOutput}
|
||||
err := fx.VerifyOperation(tx, utxos, ins, creds, outs)
|
||||
if err == nil {
|
||||
t.Fatalf("Should have errored due to a wrong number of outputs")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFxVerifyOperationWrongNumberOfInputs(t *testing.T) {
|
||||
func TestFxVerifyOperationUnknownOperation(t *testing.T) {
|
||||
vm := testVM{}
|
||||
date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
|
||||
vm.clock.Set(date)
|
||||
|
@ -733,35 +669,15 @@ func TestFxVerifyOperationWrongNumberOfInputs(t *testing.T) {
|
|||
sigBytes,
|
||||
},
|
||||
}
|
||||
mintOutput := &MintOutput{
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
}
|
||||
transferOutput := &TransferOutput{
|
||||
Amt: 1,
|
||||
Locktime: 0,
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
utxos := []interface{}{utxo}
|
||||
creds := []interface{}{cred}
|
||||
outs := []interface{}{mintOutput, transferOutput}
|
||||
err := fx.VerifyOperation(tx, utxos, nil, creds, outs)
|
||||
err := fx.VerifyOperation(tx, nil, cred, utxos)
|
||||
if err == nil {
|
||||
t.Fatalf("Should have errored due to a wrong number of inputs")
|
||||
t.Fatalf("Should have errored due to an invalid operation type")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFxVerifyOperationWrongNumberOfCredentials(t *testing.T) {
|
||||
func TestFxVerifyOperationUnknownCredential(t *testing.T) {
|
||||
vm := testVM{}
|
||||
date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
|
||||
vm.clock.Set(date)
|
||||
|
@ -780,40 +696,38 @@ func TestFxVerifyOperationWrongNumberOfCredentials(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
in := &MintInput{
|
||||
Input: Input{
|
||||
op := &MintOperation{
|
||||
MintInput: Input{
|
||||
SigIndices: []uint32{0},
|
||||
},
|
||||
}
|
||||
mintOutput := &MintOutput{
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
MintOutput: MintOutput{
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
transferOutput := &TransferOutput{
|
||||
Amt: 1,
|
||||
Locktime: 0,
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
TransferOutput: TransferOutput{
|
||||
Amt: 1,
|
||||
Locktime: 0,
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
utxos := []interface{}{utxo}
|
||||
ins := []interface{}{in}
|
||||
outs := []interface{}{mintOutput, transferOutput}
|
||||
err := fx.VerifyOperation(tx, utxos, ins, nil, outs)
|
||||
err := fx.VerifyOperation(tx, op, nil, utxos)
|
||||
if err == nil {
|
||||
t.Fatalf("Should have errored due to a wrong number of credentials")
|
||||
t.Fatalf("Should have errored due to an invalid credential type")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFxVerifyOperationWrongUTXOType(t *testing.T) {
|
||||
func TestFxVerifyOperationWrongNumberOfUTXOs(t *testing.T) {
|
||||
vm := testVM{}
|
||||
date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
|
||||
vm.clock.Set(date)
|
||||
|
@ -824,9 +738,7 @@ func TestFxVerifyOperationWrongUTXOType(t *testing.T) {
|
|||
tx := &testTx{
|
||||
bytes: txBytes,
|
||||
}
|
||||
utxo := &TransferOutput{
|
||||
Amt: 1,
|
||||
Locktime: 0,
|
||||
utxo := &MintOutput{
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
|
@ -834,46 +746,43 @@ func TestFxVerifyOperationWrongUTXOType(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
in := &MintInput{
|
||||
Input: Input{
|
||||
op := &MintOperation{
|
||||
MintInput: Input{
|
||||
SigIndices: []uint32{0},
|
||||
},
|
||||
MintOutput: MintOutput{
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
},
|
||||
TransferOutput: TransferOutput{
|
||||
Amt: 1,
|
||||
Locktime: 0,
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
cred := &Credential{
|
||||
Sigs: [][crypto.SECP256K1RSigLen]byte{
|
||||
sigBytes,
|
||||
},
|
||||
}
|
||||
mintOutput := &MintOutput{
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
}
|
||||
transferOutput := &TransferOutput{
|
||||
Amt: 1,
|
||||
Locktime: 0,
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
utxos := []interface{}{utxo}
|
||||
ins := []interface{}{in}
|
||||
creds := []interface{}{cred}
|
||||
outs := []interface{}{mintOutput, transferOutput}
|
||||
err := fx.VerifyOperation(tx, utxos, ins, creds, outs)
|
||||
utxos := []interface{}{utxo, utxo}
|
||||
err := fx.VerifyOperation(tx, op, cred, utxos)
|
||||
if err == nil {
|
||||
t.Fatalf("Should have errored due to a wrong utxo type")
|
||||
t.Fatalf("Should have errored due to a wrong number of utxos")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFxVerifyOperationWrongInputType(t *testing.T) {
|
||||
func TestFxVerifyOperationUnknownUTXOType(t *testing.T) {
|
||||
vm := testVM{}
|
||||
date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
|
||||
vm.clock.Set(date)
|
||||
|
@ -884,18 +793,27 @@ func TestFxVerifyOperationWrongInputType(t *testing.T) {
|
|||
tx := &testTx{
|
||||
bytes: txBytes,
|
||||
}
|
||||
utxo := &MintOutput{
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
op := &MintOperation{
|
||||
MintInput: Input{
|
||||
SigIndices: []uint32{0},
|
||||
},
|
||||
MintOutput: MintOutput{
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
in := &TransferInput{
|
||||
Amt: 1,
|
||||
Input: Input{
|
||||
SigIndices: []uint32{0},
|
||||
TransferOutput: TransferOutput{
|
||||
Amt: 1,
|
||||
Locktime: 0,
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
cred := &Credential{
|
||||
|
@ -903,36 +821,15 @@ func TestFxVerifyOperationWrongInputType(t *testing.T) {
|
|||
sigBytes,
|
||||
},
|
||||
}
|
||||
mintOutput := &MintOutput{
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
}
|
||||
transferOutput := &TransferOutput{
|
||||
Amt: 1,
|
||||
Locktime: 0,
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
utxos := []interface{}{utxo}
|
||||
ins := []interface{}{in}
|
||||
creds := []interface{}{cred}
|
||||
outs := []interface{}{mintOutput, transferOutput}
|
||||
err := fx.VerifyOperation(tx, utxos, ins, creds, outs)
|
||||
utxos := []interface{}{nil}
|
||||
err := fx.VerifyOperation(tx, op, cred, utxos)
|
||||
if err == nil {
|
||||
t.Fatalf("Should have errored due to a wrong input type")
|
||||
t.Fatalf("Should have errored due to an invalid utxo type")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFxVerifyOperationWrongCredentialType(t *testing.T) {
|
||||
func TestFxVerifyOperationInvalidOperationVerify(t *testing.T) {
|
||||
vm := testVM{}
|
||||
date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
|
||||
vm.clock.Set(date)
|
||||
|
@ -951,101 +848,40 @@ func TestFxVerifyOperationWrongCredentialType(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
in := &MintInput{
|
||||
Input: Input{
|
||||
op := &MintOperation{
|
||||
MintInput: Input{
|
||||
SigIndices: []uint32{0},
|
||||
},
|
||||
}
|
||||
mintOutput := &MintOutput{
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
MintOutput: MintOutput{
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
transferOutput := &TransferOutput{
|
||||
Amt: 1,
|
||||
Locktime: 0,
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
TransferOutput: TransferOutput{
|
||||
Amt: 1,
|
||||
Locktime: 0,
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
utxos := []interface{}{utxo}
|
||||
ins := []interface{}{in}
|
||||
creds := []interface{}{nil}
|
||||
outs := []interface{}{mintOutput, transferOutput}
|
||||
err := fx.VerifyOperation(tx, utxos, ins, creds, outs)
|
||||
if err == nil {
|
||||
t.Fatalf("Should have errored due to a wrong credential type")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFxVerifyOperationWrongMintType(t *testing.T) {
|
||||
vm := testVM{}
|
||||
date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
|
||||
vm.clock.Set(date)
|
||||
fx := Fx{}
|
||||
if err := fx.Initialize(&vm); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tx := &testTx{
|
||||
bytes: txBytes,
|
||||
}
|
||||
utxo := &MintOutput{
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
}
|
||||
in := &MintInput{
|
||||
Input: Input{
|
||||
SigIndices: []uint32{0},
|
||||
},
|
||||
}
|
||||
cred := &Credential{
|
||||
Sigs: [][crypto.SECP256K1RSigLen]byte{
|
||||
sigBytes,
|
||||
},
|
||||
}
|
||||
mintOutput := &TransferOutput{
|
||||
Amt: 1,
|
||||
Locktime: 0,
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
}
|
||||
transferOutput := &TransferOutput{
|
||||
Amt: 1,
|
||||
Locktime: 0,
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
utxos := []interface{}{utxo}
|
||||
ins := []interface{}{in}
|
||||
creds := []interface{}{cred}
|
||||
outs := []interface{}{mintOutput, transferOutput}
|
||||
err := fx.VerifyOperation(tx, utxos, ins, creds, outs)
|
||||
err := fx.VerifyOperation(tx, op, cred, utxos)
|
||||
if err == nil {
|
||||
t.Fatalf("Should have errored due to a wrong output type")
|
||||
t.Fatalf("Should have errored due to a failed verify")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFxVerifyOperationWrongTransferType(t *testing.T) {
|
||||
func TestFxVerifyOperationMismatchedMintOutputs(t *testing.T) {
|
||||
vm := testVM{}
|
||||
date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
|
||||
vm.clock.Set(date)
|
||||
|
@ -1064,152 +900,33 @@ func TestFxVerifyOperationWrongTransferType(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
in := &MintInput{
|
||||
Input: Input{
|
||||
op := &MintOperation{
|
||||
MintInput: Input{
|
||||
SigIndices: []uint32{0},
|
||||
},
|
||||
MintOutput: MintOutput{
|
||||
OutputOwners: OutputOwners{},
|
||||
},
|
||||
TransferOutput: TransferOutput{
|
||||
Amt: 1,
|
||||
Locktime: 0,
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
cred := &Credential{
|
||||
Sigs: [][crypto.SECP256K1RSigLen]byte{
|
||||
sigBytes,
|
||||
},
|
||||
}
|
||||
mintOutput := &MintOutput{
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
}
|
||||
transferOutput := &MintOutput{
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
utxos := []interface{}{utxo}
|
||||
ins := []interface{}{in}
|
||||
creds := []interface{}{cred}
|
||||
outs := []interface{}{mintOutput, transferOutput}
|
||||
err := fx.VerifyOperation(tx, utxos, ins, creds, outs)
|
||||
err := fx.VerifyOperation(tx, op, cred, utxos)
|
||||
if err == nil {
|
||||
t.Fatalf("Should have errored due to a wrong output type")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFxVerifyOperationInvalid(t *testing.T) {
|
||||
vm := testVM{}
|
||||
date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
|
||||
vm.clock.Set(date)
|
||||
fx := Fx{}
|
||||
if err := fx.Initialize(&vm); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tx := &testTx{
|
||||
bytes: txBytes,
|
||||
}
|
||||
utxo := &MintOutput{
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
}
|
||||
in := &MintInput{
|
||||
Input: Input{
|
||||
SigIndices: []uint32{0},
|
||||
},
|
||||
}
|
||||
cred := &Credential{
|
||||
Sigs: [][crypto.SECP256K1RSigLen]byte{
|
||||
sigBytes,
|
||||
},
|
||||
}
|
||||
mintOutput := &MintOutput{
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 0,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
}
|
||||
transferOutput := &TransferOutput{
|
||||
Amt: 1,
|
||||
Locktime: 0,
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
utxos := []interface{}{utxo}
|
||||
ins := []interface{}{in}
|
||||
creds := []interface{}{cred}
|
||||
outs := []interface{}{mintOutput, transferOutput}
|
||||
err := fx.VerifyOperation(tx, utxos, ins, creds, outs)
|
||||
if err == nil {
|
||||
t.Fatalf("Should have errored due to an invalid output")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFxVerifyOperationMismatchedMintOutput(t *testing.T) {
|
||||
vm := testVM{}
|
||||
date := time.Date(2019, time.January, 19, 16, 25, 17, 3, time.UTC)
|
||||
vm.clock.Set(date)
|
||||
fx := Fx{}
|
||||
if err := fx.Initialize(&vm); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tx := &testTx{
|
||||
bytes: txBytes,
|
||||
}
|
||||
utxo := &MintOutput{
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
}
|
||||
in := &MintInput{
|
||||
Input: Input{
|
||||
SigIndices: []uint32{0},
|
||||
},
|
||||
}
|
||||
cred := &Credential{
|
||||
Sigs: [][crypto.SECP256K1RSigLen]byte{
|
||||
sigBytes,
|
||||
},
|
||||
}
|
||||
mintOutput := &MintOutput{
|
||||
OutputOwners: OutputOwners{
|
||||
Addrs: []ids.ShortID{},
|
||||
},
|
||||
}
|
||||
transferOutput := &TransferOutput{
|
||||
Amt: 1,
|
||||
Locktime: 0,
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
utxos := []interface{}{utxo}
|
||||
ins := []interface{}{in}
|
||||
creds := []interface{}{cred}
|
||||
outs := []interface{}{mintOutput, transferOutput}
|
||||
err := fx.VerifyOperation(tx, utxos, ins, creds, outs)
|
||||
if err == nil {
|
||||
t.Fatalf("Should have errored due to a mismatched mint output")
|
||||
t.Fatalf("Should have errored due to the wrong MintOutput being created")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package secp256k1fx
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/ava-labs/gecko/vms/components/verify"
|
||||
)
|
||||
|
||||
var (
|
||||
errNilMintOperation = errors.New("nil mint operation")
|
||||
)
|
||||
|
||||
// MintOperation ...
|
||||
type MintOperation struct {
|
||||
MintInput Input `serialize:"true"`
|
||||
MintOutput MintOutput `serialize:"true"`
|
||||
TransferOutput TransferOutput `serialize:"true"`
|
||||
}
|
||||
|
||||
// Outs ...
|
||||
func (op *MintOperation) Outs() []verify.Verifiable {
|
||||
return []verify.Verifiable{&op.MintOutput, &op.TransferOutput}
|
||||
}
|
||||
|
||||
// Verify ...
|
||||
func (op *MintOperation) Verify() error {
|
||||
switch {
|
||||
case op == nil:
|
||||
return errNilMintOperation
|
||||
default:
|
||||
return verify.All(&op.MintInput, &op.MintOutput, &op.TransferOutput)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package secp256k1fx
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
)
|
||||
|
||||
func TestMintOperationVerifyNil(t *testing.T) {
|
||||
op := (*MintOperation)(nil)
|
||||
if err := op.Verify(); err == nil {
|
||||
t.Fatalf("MintOperation.Verify should have returned an error due to an nil operation")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMintOperationOuts(t *testing.T) {
|
||||
op := &MintOperation{
|
||||
MintInput: Input{
|
||||
SigIndices: []uint32{0},
|
||||
},
|
||||
MintOutput: MintOutput{
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{
|
||||
ids.NewShortID(addrBytes),
|
||||
},
|
||||
},
|
||||
},
|
||||
TransferOutput: TransferOutput{
|
||||
Amt: 1,
|
||||
Locktime: 0,
|
||||
OutputOwners: OutputOwners{
|
||||
Threshold: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
outs := op.Outs()
|
||||
if len(outs) != 2 {
|
||||
t.Fatalf("Wrong number of outputs")
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
package secp256k1fx
|
||||
|
||||
import (
|
||||
"github.com/ava-labs/gecko/utils/logging"
|
||||
"github.com/ava-labs/gecko/utils/timer"
|
||||
"github.com/ava-labs/gecko/vms/components/codec"
|
||||
)
|
||||
|
@ -12,4 +13,5 @@ import (
|
|||
type VM interface {
|
||||
Codec() codec.Codec
|
||||
Clock() *timer.Clock
|
||||
Logger() logging.Logger
|
||||
}
|
||||
|
|
|
@ -52,10 +52,10 @@ func NewWallet(log logging.Logger, networkID uint32, chainID ids.ID, txFee uint6
|
|||
c.RegisterType(&avm.OperationTx{}),
|
||||
c.RegisterType(&avm.ImportTx{}),
|
||||
c.RegisterType(&avm.ExportTx{}),
|
||||
c.RegisterType(&secp256k1fx.TransferInput{}),
|
||||
c.RegisterType(&secp256k1fx.MintOutput{}),
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{}),
|
||||
c.RegisterType(&secp256k1fx.MintInput{}),
|
||||
c.RegisterType(&secp256k1fx.TransferInput{}),
|
||||
c.RegisterType(&secp256k1fx.MintOperation{}),
|
||||
c.RegisterType(&secp256k1fx.Credential{}),
|
||||
)
|
||||
return &Wallet{
|
||||
|
|
Loading…
Reference in New Issue